Repository: kubernetes-sigs/gateway-api-inference-extension

Issue:
EPP: Version the Endpoint Picker Protocol
Currently, the Endpoint Picker (EPP) protocol spec is unversioned. As you can see from the [history](https://github.com/kubernetes-sigs/gateway-api-inference-extension/commits/main/docs/proposals/004-endpoint-picker-protocol), the spec continues to evolve with fairly frequent changes. As with other standards, the EPP protocol spec should be versioned.

Discussion:
@zhengkezhou1: /assign 

Solution patch:
diff --git a/.github/ISSUE_TEMPLATE/new-release.md b/.github/ISSUE_TEMPLATE/new-release.md
index 98fc3f4..efc6e10 100644
--- a/.github/ISSUE_TEMPLATE/new-release.md
+++ b/.github/ISSUE_TEMPLATE/new-release.md
@@ -41,7 +41,7 @@ This document defines the process for releasing Gateway API Inference Extension.
    tag has been published, set the appropriate environment variable or update the script. For example:
 
    ```shell
-   export VLLM_GPU=0.9.2
+   export VLLM_GPU=0.8.5
    export VLLM_CPU=0.9.3
    export VLLM_SIM=0.3.0
    ```
diff --git a/.github/workflows/kal.yml b/.github/workflows/kal.yml
index 618256e..17b6281 100644
--- a/.github/workflows/kal.yml
+++ b/.github/workflows/kal.yml
@@ -20,9 +20,5 @@ jobs:
           persist-credentials: false
       - name: Set up Go
         uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # tag=v5.5.0
-      - name: Install Golang CI Lint
-        run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.2.1
-      - name: Build KAL
-        run: golangci-lint custom
-      - name: run api linter
-        run: ./bin/golangci-kube-api-linter run -c ./.golangci-kal.yml ./...
+      - name: Run API Linter
+        run: make api-lint
\ No newline at end of file
diff --git a/.github/workflows/non-main-gatekeeper.yml b/.github/workflows/non-main-gatekeeper.yml
new file mode 100644
index 0000000..af91ea9
--- /dev/null
+++ b/.github/workflows/non-main-gatekeeper.yml
@@ -0,0 +1,18 @@
+name: Label non-main PRs
+
+on:
+  pull_request:
+    types: [opened, edited, synchronize, reopened]
+
+jobs:
+  add-label:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Add labels when base branch is not main
+        if: github.event.pull_request.base.ref != 'main'
+        uses: actions-ecosystem/action-add-labels@v1
+        with:
+          github_token: ${{ secrets.GITHUB_TOKEN }}
+          labels: |
+            do-not-merge/hold
+            do-not-merge/cherry-pick-not-approved
diff --git a/.golangci-kal.yml b/.golangci-kal.yml
index a5d853b..099d81d 100644
--- a/.golangci-kal.yml
+++ b/.golangci-kal.yml
@@ -32,6 +32,8 @@ linters:
                 policy: SuggestFix # SuggestFix | Warn # The policy for pointers in optional fields. Defaults to `SuggestFix`. 
               omitempty:
                 policy: SuggestFix # SuggestFix | Warn | Ignore # The policy for omitempty in optional fields. Defaults to `SuggestFix`.
+              omitzero:
+                policy: Forbid # Enforce the `omitempty` route with a pointer for all optional structs.
   exclusions:
     generated: strict
     paths:
diff --git a/Makefile b/Makefile
index ba66ef4..d956170 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,8 @@ SHELL = /usr/bin/env bash -o pipefail
 
 GIT_COMMIT_SHA ?= "$(shell git rev-parse HEAD 2>/dev/null)"
 GIT_TAG ?= $(shell git describe --tags --dirty --always)
-PLATFORMS ?= linux/amd64
+TARGETARCH ?= $(shell go env GOARCH)
+PLATFORMS ?= linux/$(TARGETARCH)
 DOCKER_BUILDX_CMD ?= docker buildx
 IMAGE_BUILD_CMD ?= $(DOCKER_BUILDX_CMD) build
 IMAGE_BUILD_EXTRA_OPTS ?=
@@ -133,12 +134,14 @@ vet: ## Run go vet against code.
 	go vet ./...
 
 .PHONY: test
-test: generate fmt vet envtest image-build verify-crds ## Run tests.
+test: generate fmt vet envtest image-build verify-crds verify-helm-charts ## Run tests.
 	CGO_ENABLED=1 KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e | grep -v /conformance) -race -coverprofile cover.out
 
 .PHONY: test-unit
 test-unit: ## Run unit tests.
-	CGO_ENABLED=1 KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./pkg/... -race -coverprofile cover.out
+	CGO_ENABLED=1 KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./pkg/... -race -coverprofile cover.out; \
+	go tool cover -func=cover.out; \
+	rm cover.out
 
 .PHONY: test-integration
 test-integration: envtest ## Run integration tests.
@@ -160,14 +163,22 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
 ci-lint: golangci-lint
 	$(GOLANGCI_LINT) run --timeout 15m0s
 
+.PHONY: api-lint
+api-lint: golangci-api-lint
+	$(GOLANGCI_API_LINT) run -c .golangci-kal.yml --timeout 15m0s ./...
+
 .PHONY: verify
-verify: vet fmt-verify generate ci-lint verify-all
+verify: vet fmt-verify generate ci-lint api-lint verify-all
 	git --no-pager diff --exit-code config api client-go
 
 .PHONY: verify-crds
 verify-crds: kubectl-validate
 	hack/verify-manifests.sh
 
+.PHONY: verify-helm-charts
+verify-helm-charts: helm-install
+	hack/verify-helm.sh
+
 # Run static analysis.
 .PHONY: verify-all
 verify-all:
@@ -297,17 +308,28 @@ live-docs:
 	docker build -t gaie/mkdocs hack/mkdocs/image
 	docker run --rm -it -p 3000:3000 -v ${PWD}:/docs gaie/mkdocs
 
-.PHONY: apix-ref-docs
-apix-ref-docs:
-	crd-ref-docs \
+.PHONY: api-ref-docs-all
+api-ref-docs-all: apix-v1a1-ref-docs apix-v1a2-ref-docs api-ref-docs
+
+.PHONY: apix-v1a1-ref-docs
+apix-v1a1-ref-docs: crd-ref-docs
+	${CRD_REF_DOCS} \
+		--source-path=${PWD}/apix/v1alpha1 \
+		--config=crd-ref-docs.yaml \
+		--renderer=markdown \
+		--output-path=${PWD}/site-src/reference/x-v1a1-spec.md
+
+.PHONY: apix-v1a2-ref-docs
+apix-v1a2-ref-docs: crd-ref-docs
+	${CRD_REF_DOCS} \
 		--source-path=${PWD}/apix/v1alpha2 \
 		--config=crd-ref-docs.yaml \
 		--renderer=markdown \
-		--output-path=${PWD}/site-src/reference/x-spec.md
+		--output-path=${PWD}/site-src/reference/x-v1a2-spec.md
 
 .PHONY: api-ref-docs
-api-ref-docs:
-	crd-ref-docs \
+api-ref-docs: crd-ref-docs
+	${CRD_REF_DOCS} \
 		--source-path=${PWD}/api \
 		--config=crd-ref-docs.yaml \
 		--renderer=markdown \
@@ -328,12 +350,12 @@ uninstall: generate kustomize ## Uninstall CRDs from the K8s cluster specified i
 	$(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -
 
 ##@ Helm
-PHONY: inferencepool-helm-chart-push
-inferencepool-helm-chart-push: yq helm
+.PHONY: inferencepool-helm-chart-push
+inferencepool-helm-chart-push: yq helm-install
 	CHART=inferencepool EXTRA_TAG="$(EXTRA_TAG)" IMAGE_REGISTRY="$(IMAGE_REGISTRY)" YQ="$(YQ)" HELM="$(HELM)" ./hack/push-chart.sh
 
-PHONY: bbr-helm-chart-push
-bbr-helm-chart-push: yq helm
+.PHONY: bbr-helm-chart-push
+bbr-helm-chart-push: yq helm-install
 	CHART=body-based-routing EXTRA_TAG="$(EXTRA_TAG)" IMAGE_REGISTRY="$(IMAGE_REGISTRY)" YQ="$(YQ)" HELM="$(HELM)" ./hack/push-chart.sh
 
 ##@ Release
@@ -364,7 +386,9 @@ KUBECTL ?= kubectl
 KUSTOMIZE ?= $(LOCALBIN)/kustomize
 CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
 ENVTEST ?= $(LOCALBIN)/setup-envtest
+CRD_REF_DOCS ?= $(LOCALBIN)/crd-ref-docs
 GOLANGCI_LINT = $(LOCALBIN)/golangci-lint
+GOLANGCI_API_LINT = $(LOCALBIN)/golangci-kube-api-linter
 HELM = $(PROJECT_DIR)/bin/helm
 YQ = $(PROJECT_DIR)/bin/yq
 KUBECTL_VALIDATE = $(PROJECT_DIR)/bin/kubectl-validate
@@ -372,12 +396,14 @@ GCI = $(LOCALBIN)/gci
 
 ## Tool Versions
 KUSTOMIZE_VERSION ?= v5.4.3
-CONTROLLER_TOOLS_VERSION ?= v0.16.1
+CONTROLLER_TOOLS_VERSION ?= v0.19.0
 ENVTEST_VERSION ?= release-0.19
+CRD_REF_DOCS_VERSION ?= v0.2.0
 GOLANGCI_LINT_VERSION ?= v2.3.0
 HELM_VERSION ?= v3.17.1
 KUBECTL_VALIDATE_VERSION ?= v0.0.4
 GCI_VERSION ?= v0.13.6
+YQ_VERSION ?= v4.45.1
 
 .PHONY: kustomize
 kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
@@ -389,6 +415,11 @@ controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessar
 $(CONTROLLER_GEN): $(LOCALBIN)
 	$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION))
 
+.PHONY: crd-ref-docs
+crd-ref-docs: $(CRD_REF_DOCS) ## Download crd-ref-docs locally if necessary.
+$(CRD_REF_DOCS): $(LOCALBIN)
+	$(call go-install-tool,$(CRD_REF_DOCS),github.com/elastic/crd-ref-docs,$(CRD_REF_DOCS_VERSION))
+
 .PHONY: envtest
 envtest: $(ENVTEST) ## Download setup-envtest locally if necessary.
 $(ENVTEST): $(LOCALBIN)
@@ -399,12 +430,18 @@ golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
 $(GOLANGCI_LINT): $(LOCALBIN)
 	$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/v2/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION))
 
+.PHONY: golangci-api-lint
+golangci-api-lint: golangci-lint $(GOLANGCI_API_LINT) ## Download golangci-lint locally if necessary before building KAL
+$(GOLANGCI_API_LINT):
+	$(GOLANGCI_LINT) custom
+
 .PHONY: yq
 yq: ## Download yq locally if necessary.
-	GOBIN=$(PROJECT_DIR)/bin GO111MODULE=on go install github.com/mikefarah/yq/v4@v4.45.1
+	GOBIN=$(PROJECT_DIR)/bin GO111MODULE=on go install github.com/mikefarah/yq/v4@$(YQ_VERSION)
 
-.PHONY: helm
-helm: ## Download helm locally if necessary.
+.PHONY: helm-install
+helm-install: $(HELM) ## Download helm locally if necessary.
+$(HELM): $(LOCALBIN)
 	GOBIN=$(PROJECT_DIR)/bin GO111MODULE=on go install helm.sh/helm/v3/cmd/helm@$(HELM_VERSION)
 
 .PHONY: kubectl-validate
diff --git a/OWNERS b/OWNERS
index ecb73d5..596ad1b 100644
--- a/OWNERS
+++ b/OWNERS
@@ -2,7 +2,6 @@
 
 approvers:
 - gateway-api-inference-extension-maintainers
-- wg-serving-leads
 
 reviewers:
 - gateway-api-inference-extension-reviewers
diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES
index 32a0493..4ccd573 100644
--- a/OWNERS_ALIASES
+++ b/OWNERS_ALIASES
@@ -9,13 +9,6 @@ aliases:
   - kfswain
 
   gateway-api-inference-extension-reviewers:
+  - elevran
   - liu-cong
   - robscott
-  - shaneutt
-
-
-  wg-serving-leads:
-  - ArangoGutierrez
-  - Jeffwan
-  - SergeyKanzhelev
-  - terrytangyuan
diff --git a/README.md b/README.md
index 51aaf28..19e801b 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,8 @@ The following specific terms to this project:
   performance, availability and capabilities to optimize routing. Includes
   things like [Prefix Cache] status or [LoRA Adapters] availability.
 - **Endpoint Picker(EPP)**: An implementation of an `Inference Scheduler` with additional Routing, Flow, and Request Control layers to allow for sophisticated routing strategies. Additional info on the architecture of the EPP [here](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals/0683-epp-architecture-proposal).
-  
+- **Body Based Router(BBR)**: An optional additional [ext-proc](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_proc_filter) server that parses the http body of the inference prompt message and extracts information (currently the model name for OpenAI API style messages) into a format which can then be used by the gateway for routing purposes. Additional info [here](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/pkg/bbr/README.md) and in the documentation [user guides](https://gateway-api-inference-extension.sigs.k8s.io/guides/). 
+ 
 
 The following are key industry terms that are important to understand for
 this project:
diff --git a/api/v1/inferencepool_types.go b/api/v1/inferencepool_types.go
index ed8e0e1..92e7aff 100644
--- a/api/v1/inferencepool_types.go
+++ b/api/v1/inferencepool_types.go
@@ -24,7 +24,7 @@ import (
 //
 // +kubebuilder:object:root=true
 // TODO: change the annotation once it gets officially approved
-// +kubebuilder:metadata:annotations="api-approved.kubernetes.io=unapproved, experimental-only"
+// +kubebuilder:metadata:annotations="api-approved.kubernetes.io=https://github.com/kubernetes-sigs/gateway-api-inference-extension/pull/1173"
 // +kubebuilder:resource:shortName=infpool
 // +kubebuilder:subresource:status
 // +kubebuilder:storageversion
@@ -35,17 +35,19 @@ type InferencePool struct {
 	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
+	// Spec defines the desired state of the InferencePool.
+	//
 	// +required
 	Spec InferencePoolSpec `json:"spec,omitzero"`
 
-	// Status defines the observed state of InferencePool.
+	// Status defines the observed state of the InferencePool.
 	//
-	// +kubebuilder:default={parent: {{parentRef: {kind: "Status", name: "default"}, conditions: {{type: "Accepted", status: "Unknown", reason: "Pending", message: "Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}}}}
 	// +optional
-	Status InferencePoolStatus `json:"status,omitzero"`
+	//nolint:kubeapilinter // status should not be a pointer.
+	Status InferencePoolStatus `json:"status,omitempty"`
 }
 
-// InferencePoolList contains a list of InferencePool.
+// InferencePoolList contains a list of InferencePools.
 //
 // +kubebuilder:object:root=true
 type InferencePoolList struct {
@@ -54,7 +56,7 @@ type InferencePoolList struct {
 	Items           []InferencePool `json:"items"`
 }
 
-// InferencePoolSpec defines the desired state of InferencePool
+// InferencePoolSpec defines the desired state of the InferencePool.
 type InferencePoolSpec struct {
 	// Selector determines which Pods are members of this inference pool.
 	// It matches Pods by their labels only within the same namespace; cross-namespace
@@ -65,20 +67,24 @@ type InferencePoolSpec struct {
 	// this configuration into a Service resource.
 	//
 	// +required
-	Selector LabelSelector `json:"selector,omitempty,omitzero"`
+	Selector LabelSelector `json:"selector,omitzero"`
 
 	// TargetPorts defines a list of ports that are exposed by this InferencePool.
-	// Currently, the list may only include a single port definition.
+	// Every port will be treated as a distinctive endpoint by EPP,
+	// addressable as a 'podIP:portNumber' combination.
+	//
 	// +kubebuilder:validation:MinItems=1
-	// +kubebuilder:validation:MaxItems=1
-	// +listType=map
-	// +listMapKey=number
+	// +kubebuilder:validation:MaxItems=8
+	// +kubebuilder:validation:XValidation:message="port number must be unique",rule="self.all(p1, self.exists_one(p2, p1.number==p2.number))"
+	// +listType=atomic
 	// +required
 	TargetPorts []Port `json:"targetPorts,omitempty"`
 
-	// Extension configures an endpoint picker as an extension service.
+	// EndpointPickerRef is a reference to the Endpoint Picker extension and its
+	// associated configuration.
+	//
 	// +required
-	ExtensionRef Extension `json:"extensionRef,omitempty,omitzero"`
+	EndpointPickerRef EndpointPickerRef `json:"endpointPickerRef,omitzero"`
 }
 
 // Port defines the network port that will be exposed by this InferencePool.
@@ -90,10 +96,12 @@ type Port struct {
 	Number PortNumber `json:"number,omitempty"`
 }
 
-// Extension specifies how to configure an extension that runs the endpoint picker.
-type Extension struct {
-	// Group is the group of the referent.
-	// The default value is "", representing the Core API group.
+// EndpointPickerRef specifies a reference to an Endpoint Picker extension and its
+// associated configuration.
+// +kubebuilder:validation:XValidation:rule="self.kind != 'Service' || has(self.port)",message="port is required when kind is 'Service' or unspecified (defaults to 'Service')"
+type EndpointPickerRef struct {
+	// Group is the group of the referent API object. When unspecified, the default value
+	// is "", representing the Core API group.
 	//
 	// +optional
 	// +kubebuilder:default=""
@@ -101,6 +109,8 @@ type Extension struct {
 
 	// Kind is the Kubernetes resource kind of the referent.
 	//
+	// Required if the referent is ambiguous, e.g. service with multiple ports.
+	//
 	// Defaults to "Service" when not specified.
 	//
 	// ExternalName services can refer to CNAME DNS records that may live
@@ -113,64 +123,69 @@ type Extension struct {
 	// +kubebuilder:default=Service
 	Kind Kind `json:"kind,omitempty"`
 
-	// Name is the name of the referent.
+	// Name is the name of the referent API object.
 	//
 	// +required
 	Name ObjectName `json:"name,omitempty"`
 
-	// The port number on the service running the extension. When unspecified,
-	// implementations SHOULD infer a default value of 9002 when the Kind is
-	// Service.
+	// Port is the port of the Endpoint Picker extension service.
+	//
+	// Port is required when the referent is a Kubernetes Service. In this
+	// case, the port number is the service port number, not the target port.
+	// For other resources, destination port might be derived from the referent
+	// resource or this field.
 	//
 	// +optional
-	PortNumber PortNumber `json:"portNumber,omitempty"`
+	Port *Port `json:"port,omitempty"`
 
-	// Configures how the gateway handles the case when the extension is not responsive.
-	// Defaults to failClose.
+	// FailureMode configures how the parent handles the case when the Endpoint Picker extension
+	// is non-responsive. When unspecified, defaults to "FailClose".
 	//
 	// +optional
 	// +kubebuilder:default="FailClose"
-	FailureMode ExtensionFailureMode `json:"failureMode,omitempty"`
+	FailureMode EndpointPickerFailureMode `json:"failureMode,omitempty"`
 }
 
-// ExtensionFailureMode defines the options for how the gateway handles the case when the extension is not
-// responsive.
+// EndpointPickerFailureMode defines the options for how the parent handles the case when the
+// Endpoint Picker extension is non-responsive.
+//
 // +kubebuilder:validation:Enum=FailOpen;FailClose
-type ExtensionFailureMode string
+type EndpointPickerFailureMode string
 
 const (
-	// FailOpen specifies that the proxy should forward the request to an endpoint of its picking when the Endpoint Picker fails.
-	FailOpen ExtensionFailureMode = "FailOpen"
-	// FailClose specifies that the proxy should drop the request when the Endpoint Picker fails.
-	FailClose ExtensionFailureMode = "FailClose"
+	// EndpointPickerFailOpen specifies that the parent should forward the request to an endpoint
+	// of its picking when the Endpoint Picker extension fails.
+	EndpointPickerFailOpen EndpointPickerFailureMode = "FailOpen"
+	// EndpointPickerFailClose specifies that the parent should drop the request when the Endpoint
+	// Picker extension fails.
+	EndpointPickerFailClose EndpointPickerFailureMode = "FailClose"
 )
 
-// InferencePoolStatus defines the observed state of InferencePool.
-// +kubebuilder:validation:MinProperties=1
+// InferencePoolStatus defines the observed state of the InferencePool.
 type InferencePoolStatus struct {
-	// Parents is a list of parent resources (usually Gateways) that are
-	// associated with the InferencePool, and the status of the InferencePool with respect to
-	// each parent.
+	// Parents is a list of parent resources, typically Gateways, that are associated with
+	// the InferencePool, and the status of the InferencePool with respect to each parent.
 	//
-	// A maximum of 32 Gateways will be represented in this list. When the list contains
-	// `kind: Status, name: default`, it indicates that the InferencePool is not
-	// associated with any Gateway and a controller must perform the following:
+	// A controller that manages the InferencePool, must add an entry for each parent it manages
+	// and remove the parent entry when the controller no longer considers the InferencePool to
+	// be associated with that parent.
 	//
-	//  - Remove the parent when setting the "Accepted" condition.
-	//  - Add the parent when the controller will no longer manage the InferencePool
-	//    and no other parents exist.
+	// A maximum of 32 parents will be represented in this list. When the list is empty,
+	// it indicates that the InferencePool is not associated with any parents.
 	//
 	// +kubebuilder:validation:MaxItems=32
 	// +optional
 	// +listType=atomic
-	Parents []PoolStatus `json:"parent,omitempty"`
+	Parents []ParentStatus `json:"parents,omitempty"`
 }
 
-// PoolStatus defines the observed state of InferencePool from a Gateway.
-type PoolStatus struct {
-	// Conditions track the state of the InferencePool.
+// ParentStatus defines the observed state of InferencePool from a Parent, i.e. Gateway.
+type ParentStatus struct {
+	// Conditions is a list of status conditions that provide information about the observed
+	// state of the InferencePool. This field is required to be set by the controller that
+	// manages the InferencePool.
 	//
-	// Known condition types are:
+	// Supported condition types are:
 	//
 	// * "Accepted"
 	// * "ResolvedRefs"
@@ -179,31 +194,67 @@ type PoolStatus struct {
 	// +listType=map
 	// +listMapKey=type
 	// +kubebuilder:validation:MaxItems=8
-	// +kubebuilder:default={{type: "Accepted", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}
 	Conditions []metav1.Condition `json:"conditions,omitempty"`
 
-	// GatewayRef indicates the gateway that observed state of InferencePool.
+	// ParentRef is used to identify the parent resource that this status
+	// is associated with. It is used to match the InferencePool with the parent
+	// resource, such as a Gateway.
+	//
 	// +required
-	GatewayRef ParentGatewayReference `json:"parentRef,omitzero"`
+	ParentRef ParentReference `json:"parentRef,omitzero"`
+
+	// ControllerName is a domain/path string that indicates the name of the controller that
+	// wrote this status. This corresponds with the GatewayClass controllerName field when the
+	// parentRef references a Gateway kind.
+	//
+	// Example: "example.net/gateway-controller".
+	//
+	// The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are valid Kubernetes names:
+	//
+	//  https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+	//
+	// Controllers MAY populate this field when writing status. When populating this field, controllers
+	// should ensure that entries to status populated with their ControllerName are cleaned up when they
+	// are no longer necessary.
+	//
+	// +optional
+	ControllerName ControllerName `json:"controllerName,omitempty"`
 }
 
-// InferencePoolConditionType is a type of condition for the InferencePool
+// ControllerName is the name of a controller that manages ParentStatus. It must be a domain prefixed
+// path.
+//
+// Valid values include:
+//
+// * "example.com/bar"
+//
+// Invalid values include:
+//
+// * "example.com" - must include path
+// * "foo.example.com" - must include path
+//
+// +kubebuilder:validation:MinLength=1
+// +kubebuilder:validation:MaxLength=253
+// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$`
+type ControllerName string
+
+// InferencePoolConditionType is a type of status condition for the InferencePool.
 type InferencePoolConditionType string
 
-// InferencePoolReason is the reason for a given InferencePoolConditionType
+// InferencePoolReason is the reason for a type of InferencePool status condition.
 type InferencePoolReason string
 
 const (
-	// This condition indicates whether the InferencePool has been accepted or rejected
-	// by a Gateway, and why.
+	// InferencePoolConditionAccepted is a type of condition that indicates whether
+	// the InferencePool has been accepted or rejected by a Parent, and why.
 	//
 	// Possible reasons for this condition to be True are:
 	//
-	// * "Accepted"
+	// * "SupportedByParent"
 	//
 	// Possible reasons for this condition to be False are:
 	//
-	// * "NotSupportedByGateway"
+	// * "Accepted"
 	// * "HTTPRouteNotAccepted"
 	//
 	// Possible reasons for this condition to be Unknown are:
@@ -214,28 +265,26 @@ const (
 	// prefer to use the reasons listed above to improve interoperability.
 	InferencePoolConditionAccepted InferencePoolConditionType = "Accepted"
 
-	// This reason is used with the "Accepted" condition when the InferencePool has been
-	// accepted by the Gateway.
+	// InferencePoolReasonAccepted is a reason used with the "Accepted" condition
+	// when the InferencePool is accepted by a Parent because the Parent supports
+	// InferencePool as a backend.
 	InferencePoolReasonAccepted InferencePoolReason = "Accepted"
 
-	// This reason is used with the "Accepted" condition when the InferencePool
-	// has not been accepted by a Gateway because the Gateway does not support
-	// InferencePool as a backend.
-	InferencePoolReasonNotSupportedByGateway InferencePoolReason = "NotSupportedByGateway"
+	// InferencePoolReasonNotSupportedByParent is a reason used with the "Accepted"
+	// condition when the InferencePool has not been accepted by a Parent because
+	// the Parent does not support InferencePool as a backend.
+	InferencePoolReasonNotSupportedByParent InferencePoolReason = "NotSupportedByParent"
 
-	// This reason is used with the "Accepted" condition when the InferencePool is
-	// referenced by an HTTPRoute that has been rejected by the Gateway. The user
-	// should inspect the status of the referring HTTPRoute for the specific reason.
+	// InferencePoolReasonHTTPRouteNotAccepted is an optional reason used with the
+	// "Accepted" condition when the InferencePool is referenced by an HTTPRoute that
+	// has been rejected by the Parent. The user should inspect the status of the
+	// referring HTTPRoute for the specific reason.
 	InferencePoolReasonHTTPRouteNotAccepted InferencePoolReason = "HTTPRouteNotAccepted"
-
-	// This reason is used with the "Accepted" when a controller has not yet
-	// reconciled the InferencePool.
-	InferencePoolReasonPending InferencePoolReason = "Pending"
 )
 
 const (
-	// This condition indicates whether the controller was able to resolve all
-	// the object references for the InferencePool.
+	// InferencePoolConditionResolvedRefs is a type of condition that indicates whether
+	// the controller was able to resolve all the object references for the InferencePool.
 	//
 	// Possible reasons for this condition to be True are:
 	//
@@ -249,38 +298,77 @@ const (
 	// prefer to use the reasons listed above to improve interoperability.
 	InferencePoolConditionResolvedRefs InferencePoolConditionType = "ResolvedRefs"
 
-	// This reason is used with the "ResolvedRefs" condition when the condition
-	// is true.
+	// InferencePoolReasonResolvedRefs is a reason used with the "ResolvedRefs"
+	// condition when the condition is true.
 	InferencePoolReasonResolvedRefs InferencePoolReason = "ResolvedRefs"
 
-	// This reason is used with the "ResolvedRefs" condition when the
-	// Extension is invalid in some way. This can include an unsupported kind
-	// or API group, or a reference to a resource that can not be found.
+	// InferencePoolReasonInvalidExtensionRef is a reason used with the "ResolvedRefs"
+	// condition when the Extension is invalid in some way. This can include an
+	// unsupported kind or API group, or a reference to a resource that cannot be found.
 	InferencePoolReasonInvalidExtensionRef InferencePoolReason = "InvalidExtensionRef"
 )
 
-// ParentGatewayReference identifies an API object including its namespace,
-// defaulting to Gateway.
-type ParentGatewayReference struct {
-	// Group is the group of the referent.
+const (
+	// InferencePoolConditionExported is a type of condition that indicates whether the
+	// controller was able to export the InferencePool to the specified clusters.
+	//
+	// Possible reasons for this condition to be True are:
+	//
+	// * "Exported"
+	//
+	// Possible reasons for this condition to be False are:
+	//
+	// * "NotRequested"
+	// * "NotSupported"
+	//
+	// Controllers MAY raise this condition with other reasons, but should
+	// prefer to use the reasons listed above to improve interoperability.
+	InferencePoolConditionExported InferencePoolConditionType = "Exported"
+
+	// InferencePoolReasonExported is a reason used with the "Exported" condition when the
+	// condition is true.
+	InferencePoolReasonExported InferencePoolReason = "Exported"
+
+	// InferencePoolReasonNotRequested is a reason used with the "Exported" condition when the
+	// condition is false and no export was requested by the InferencePool. This indicates a
+	// deliberate non-action rather than an error.
+	InferencePoolReasonNotRequested InferencePoolReason = "NotRequested"
+
+	// InferencePoolReasonNotSupported is a reason used with the "Exported" condition when the
+	// condition is false and the export was requested but is not supported by the implementation.
+	// Controllers should include details in the condition message.
+	InferencePoolReasonNotSupported InferencePoolReason = "NotSupported"
+)
+
+// ParentReference identifies an API object. It is used to associate the InferencePool with a
+// parent resource, such as a Gateway.
+type ParentReference struct {
+	// Group is the group of the referent API object. When unspecified, the referent is assumed
+	// to be in the "gateway.networking.k8s.io" API group.
 	//
 	// +optional
 	// +kubebuilder:default="gateway.networking.k8s.io"
 	Group *Group `json:"group,omitempty"`
 
-	// Kind is kind of the referent. For example "Gateway".
+	// Kind is the kind of the referent API object. When unspecified, the referent is assumed
+	// to be a "Gateway" kind.
 	//
 	// +optional
 	// +kubebuilder:default=Gateway
 	Kind Kind `json:"kind,omitempty"`
 
-	// Name is the name of the referent.
+	// Name is the name of the referent API object.
+	//
 	// +required
 	Name ObjectName `json:"name,omitempty"`
 
-	// Namespace is the namespace of the referent.  If not present,
-	// the namespace of the referent is assumed to be the same as
-	// the namespace of the referring object.
+	// Namespace is the namespace of the referenced object. When unspecified, the local
+	// namespace is inferred.
+	//
+	// Note that when a namespace different than the local namespace is specified,
+	// a ReferenceGrant object is required in the referent namespace to allow that
+	// namespace's owner to accept the reference. See the ReferenceGrant
+	// documentation for details: https://gateway-api.sigs.k8s.io/api-types/referencegrant/
 	//
 	// +optional
 	Namespace Namespace `json:"namespace,omitempty"`
diff --git a/api/v1/shared_types.go b/api/v1/shared_types.go
index 64425e7..bc315fd 100644
--- a/api/v1/shared_types.go
+++ b/api/v1/shared_types.go
@@ -132,11 +132,12 @@ type LabelValue string
 // LabelSelector defines a query for resources based on their labels.
 // This simplified version uses only the matchLabels field.
 type LabelSelector struct {
-	// matchLabels contains a set of required {key,value} pairs.
+	// MatchLabels contains a set of required {key,value} pairs.
 	// An object must match every label in this map to be selected.
 	// The matching logic is an AND operation on all entries.
 	//
 	// +required
+	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=64
-	MatchLabels map[LabelKey]LabelValue `json:"matchLabels,omitempty" protobuf:"bytes,1,rep,name=matchLabels"`
+	MatchLabels map[LabelKey]LabelValue `json:"matchLabels,omitempty"`
 }
diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go
index 0cdf170..3b00363 100644
--- a/api/v1/zz_generated.deepcopy.go
+++ b/api/v1/zz_generated.deepcopy.go
@@ -26,21 +26,26 @@ import (
 )
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Extension) DeepCopyInto(out *Extension) {
+func (in *EndpointPickerRef) DeepCopyInto(out *EndpointPickerRef) {
 	*out = *in
 	if in.Group != nil {
 		in, out := &in.Group, &out.Group
 		*out = new(Group)
 		**out = **in
 	}
+	if in.Port != nil {
+		in, out := &in.Port, &out.Port
+		*out = new(Port)
+		**out = **in
+	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Extension.
-func (in *Extension) DeepCopy() *Extension {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointPickerRef.
+func (in *EndpointPickerRef) DeepCopy() *EndpointPickerRef {
 	if in == nil {
 		return nil
 	}
-	out := new(Extension)
+	out := new(EndpointPickerRef)
 	in.DeepCopyInto(out)
 	return out
 }
@@ -113,7 +118,7 @@ func (in *InferencePoolSpec) DeepCopyInto(out *InferencePoolSpec) {
 		*out = make([]Port, len(*in))
 		copy(*out, *in)
 	}
-	in.ExtensionRef.DeepCopyInto(&out.ExtensionRef)
+	in.EndpointPickerRef.DeepCopyInto(&out.EndpointPickerRef)
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InferencePoolSpec.
@@ -131,7 +136,7 @@ func (in *InferencePoolStatus) DeepCopyInto(out *InferencePoolStatus) {
 	*out = *in
 	if in.Parents != nil {
 		in, out := &in.Parents, &out.Parents
-		*out = make([]PoolStatus, len(*in))
+		*out = make([]ParentStatus, len(*in))
 		for i := range *in {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
@@ -171,7 +176,7 @@ func (in *LabelSelector) DeepCopy() *LabelSelector {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ParentGatewayReference) DeepCopyInto(out *ParentGatewayReference) {
+func (in *ParentReference) DeepCopyInto(out *ParentReference) {
 	*out = *in
 	if in.Group != nil {
 		in, out := &in.Group, &out.Group
@@ -180,18 +185,18 @@ func (in *ParentGatewayReference) DeepCopyInto(out *ParentGatewayReference) {
 	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentGatewayReference.
-func (in *ParentGatewayReference) DeepCopy() *ParentGatewayReference {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentReference.
+func (in *ParentReference) DeepCopy() *ParentReference {
 	if in == nil {
 		return nil
 	}
-	out := new(ParentGatewayReference)
+	out := new(ParentReference)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *PoolStatus) DeepCopyInto(out *PoolStatus) {
+func (in *ParentStatus) DeepCopyInto(out *ParentStatus) {
 	*out = *in
 	if in.Conditions != nil {
 		in, out := &in.Conditions, &out.Conditions
@@ -200,15 +205,15 @@ func (in *PoolStatus) DeepCopyInto(out *PoolStatus) {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
 	}
-	in.GatewayRef.DeepCopyInto(&out.GatewayRef)
+	in.ParentRef.DeepCopyInto(&out.ParentRef)
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolStatus.
-func (in *PoolStatus) DeepCopy() *PoolStatus {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentStatus.
+func (in *ParentStatus) DeepCopy() *ParentStatus {
 	if in == nil {
 		return nil
 	}
-	out := new(PoolStatus)
+	out := new(ParentStatus)
 	in.DeepCopyInto(out)
 	return out
 }
diff --git a/apix/v1alpha1/doc.go b/apix/v1alpha1/doc.go
new file mode 100644
index 0000000..122c3b9
--- /dev/null
+++ b/apix/v1alpha1/doc.go
@@ -0,0 +1,22 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package v1alpha1 contains API Schema definitions for the
+// inference.networking.x-k8s.io API group.
+//
+// +kubebuilder:object:generate=true
+// +groupName=inference.networking.x-k8s.io
+package v1alpha1
diff --git a/apix/v1alpha1/inferencepoolimport_types.go b/apix/v1alpha1/inferencepoolimport_types.go
new file mode 100644
index 0000000..2239aa3
--- /dev/null
+++ b/apix/v1alpha1/inferencepoolimport_types.go
@@ -0,0 +1,143 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+)
+
+// InferencePoolImport is the Schema for the InferencePoolImports API.
+//
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:shortName=infpimp
+// +kubebuilder:subresource:status
+// +kubebuilder:storageversion
+// +genclient
+type InferencePoolImport struct {
+	metav1.TypeMeta `json:",inline"`
+
+	// +optional
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	// Status defines the observed state of the InferencePoolImport.
+	//
+	// +optional
+	//nolint:kubeapilinter // status should not be a pointer.
+	Status InferencePoolImportStatus `json:"status,omitempty"`
+}
+
+// InferencePoolImportList contains a list of InferencePoolImports.
+//
+// +kubebuilder:object:root=true
+type InferencePoolImportList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []InferencePoolImport `json:"items"`
+}
+
+// InferencePoolImportStatus defines the observed state of the InferencePoolImport.
+type InferencePoolImportStatus struct {
+	// Controllers is a list of controllers that are responsible for managing the InferencePoolImport.
+	//
+	// +listType=map
+	// +listMapKey=name
+	// +kubebuilder:validation:MaxItems=8
+	// +kubebuilder:validation:Required
+	Controllers []ImportController `json:"controllers"`
+}
+
+// ImportController defines a controller that is responsible for managing the InferencePoolImport.
+type ImportController struct {
+	// Name is a domain/path string that indicates the name of the controller that manages the
+	// InferencePoolImport. Name corresponds to the GatewayClass controllerName field when the
+	// controller will manage parents of type "Gateway". Otherwise, the name is implementation-specific.
+	//
+	// Example: "example.net/import-controller".
+	//
+	// The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are valid Kubernetes
+	// names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+	//
+	// A controller MUST populate this field when writing status and ensure that entries to status
+	// populated with their controller name are removed when they are no longer necessary.
+	//
+	// +required
+	Name ControllerName `json:"name"`
+
+	// ExportingClusters is a list of clusters that exported the InferencePool(s) that back the
+	// InferencePoolImport. Required when the controller is responsible for CRUD'ing the InferencePoolImport
+	// from the exported InferencePool(s).
+	//
+	// +optional
+	ExportingClusters []ExportingCluster `json:"exportingClusters,omitempty"`
+
+	// Parents is a list of parent resources, typically Gateways, that are associated with the
+	// InferencePoolImport, and the status of the InferencePoolImport with respect to each parent.
+	//
+	// Ancestor would be a more accurate name, but Parent is consistent with InferencePool terminology.
+	//
+	// Required when the controller manages the InferencePoolImport as an HTTPRoute backendRef. The controller
+	// must add an entry for each parent it manages and remove the parent entry when the controller no longer
+	// considers the InferencePoolImport to be associated with that parent.
+	//
+	// +optional
+	// +listType=atomic
+	Parents []v1.ParentStatus `json:"parents,omitempty"`
+
+	// Conditions track the state of the InferencePoolImport.
+	//
+	// Known condition types are:
+	//
+	//  * "Accepted"
+	//
+	// +optional
+	// +listType=map
+	// +listMapKey=type
+	// +kubebuilder:validation:MaxItems=8
+	Conditions []metav1.Condition `json:"conditions,omitempty"`
+}
+
+// ControllerName is the name of a controller that manages a resource. It must be a domain prefixed path.
+//
+// Valid values include:
+//
+//   - "example.com/bar"
+//
+// Invalid values include:
+//
+//   - "example.com" - must include path
+//   - "foo.example.com" - must include path
+//
+// +kubebuilder:validation:MinLength=1
+// +kubebuilder:validation:MaxLength=253
+// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$`
+type ControllerName string
+
+// ClusterName is the name of a cluster that exported the InferencePool.
+//
+// +kubebuilder:validation:MinLength=1
+// +kubebuilder:validation:MaxLength=253
+type ClusterName string
+
+// ExportingCluster defines a cluster that exported the InferencePool that backs this InferencePoolImport.
+type ExportingCluster struct {
+	// Name of the exporting cluster (must be unique within the list).
+	//
+	// +kubebuilder:validation:Required
+	Name ClusterName `json:"name"`
+}
diff --git a/apix/v1alpha1/shared_types.go b/apix/v1alpha1/shared_types.go
new file mode 100644
index 0000000..56fd71d
--- /dev/null
+++ b/apix/v1alpha1/shared_types.go
@@ -0,0 +1,24 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+// ExportAnnotationKey is the annotation key used to export an InferencePool.
+var ExportAnnotationKey = "inference.networking.x-k8s.io/export"
+
+// ExportAnnotationVal is the annotation value used to export an InferencePool
+// to all clusters.
+var ExportAnnotationVal = "ClusterSet"
diff --git a/apix/v1alpha1/zz_generated.deepcopy.go b/apix/v1alpha1/zz_generated.deepcopy.go
new file mode 100644
index 0000000..f6f1826
--- /dev/null
+++ b/apix/v1alpha1/zz_generated.deepcopy.go
@@ -0,0 +1,156 @@
+//go:build !ignore_autogenerated
+
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by controller-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+	"sigs.k8s.io/gateway-api-inference-extension/api/v1"
+)
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ExportingCluster) DeepCopyInto(out *ExportingCluster) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportingCluster.
+func (in *ExportingCluster) DeepCopy() *ExportingCluster {
+	if in == nil {
+		return nil
+	}
+	out := new(ExportingCluster)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ImportController) DeepCopyInto(out *ImportController) {
+	*out = *in
+	if in.ExportingClusters != nil {
+		in, out := &in.ExportingClusters, &out.ExportingClusters
+		*out = make([]ExportingCluster, len(*in))
+		copy(*out, *in)
+	}
+	if in.Parents != nil {
+		in, out := &in.Parents, &out.Parents
+		*out = make([]v1.ParentStatus, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+	if in.Conditions != nil {
+		in, out := &in.Conditions, &out.Conditions
+		*out = make([]metav1.Condition, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImportController.
+func (in *ImportController) DeepCopy() *ImportController {
+	if in == nil {
+		return nil
+	}
+	out := new(ImportController)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InferencePoolImport) DeepCopyInto(out *InferencePoolImport) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Status.DeepCopyInto(&out.Status)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InferencePoolImport.
+func (in *InferencePoolImport) DeepCopy() *InferencePoolImport {
+	if in == nil {
+		return nil
+	}
+	out := new(InferencePoolImport)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *InferencePoolImport) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InferencePoolImportList) DeepCopyInto(out *InferencePoolImportList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]InferencePoolImport, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InferencePoolImportList.
+func (in *InferencePoolImportList) DeepCopy() *InferencePoolImportList {
+	if in == nil {
+		return nil
+	}
+	out := new(InferencePoolImportList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *InferencePoolImportList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InferencePoolImportStatus) DeepCopyInto(out *InferencePoolImportStatus) {
+	*out = *in
+	if in.Controllers != nil {
+		in, out := &in.Controllers, &out.Controllers
+		*out = make([]ImportController, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InferencePoolImportStatus.
+func (in *InferencePoolImportStatus) DeepCopy() *InferencePoolImportStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(InferencePoolImportStatus)
+	in.DeepCopyInto(out)
+	return out
+}
diff --git a/apix/v1alpha1/zz_generated.register.go b/apix/v1alpha1/zz_generated.register.go
new file mode 100644
index 0000000..4894b76
--- /dev/null
+++ b/apix/v1alpha1/zz_generated.register.go
@@ -0,0 +1,70 @@
+//go:build !ignore_autogenerated
+// +build !ignore_autogenerated
+
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by register-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+	schema "k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+// GroupName specifies the group name used to register the objects.
+const GroupName = "inference.networking.x-k8s.io"
+
+// GroupVersion specifies the group and the version used to register the objects.
+var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"}
+
+// SchemeGroupVersion is group version used to register these objects
+// Deprecated: use GroupVersion instead.
+var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
+
+// Resource takes an unqualified resource and returns a Group qualified GroupResource
+func Resource(resource string) schema.GroupResource {
+	return SchemeGroupVersion.WithResource(resource).GroupResource()
+}
+
+var (
+	// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
+	SchemeBuilder      runtime.SchemeBuilder
+	localSchemeBuilder = &SchemeBuilder
+	// Deprecated: use Install instead
+	AddToScheme = localSchemeBuilder.AddToScheme
+	Install     = localSchemeBuilder.AddToScheme
+)
+
+func init() {
+	// We only register manually written functions here. The registration of the
+	// generated functions takes place in the generated files. The separation
+	// makes the code compile even when the generated files are missing.
+	localSchemeBuilder.Register(addKnownTypes)
+}
+
+// Adds the list of known types to Scheme.
+func addKnownTypes(scheme *runtime.Scheme) error {
+	scheme.AddKnownTypes(SchemeGroupVersion,
+		&InferencePoolImport{},
+		&InferencePoolImportList{},
+	)
+	// AddToGroupVersion allows the serialization of client types like ListOptions.
+	v1.AddToGroupVersion(scheme, SchemeGroupVersion)
+	return nil
+}
diff --git a/apix/v1alpha2/inferenceobjective_types.go b/apix/v1alpha2/inferenceobjective_types.go
index 07f2c4d..691b881 100644
--- a/apix/v1alpha2/inferenceobjective_types.go
+++ b/apix/v1alpha2/inferenceobjective_types.go
@@ -25,7 +25,6 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:subresource:status
 // +kubebuilder:storageversion
-// +kubebuilder:printcolumn:name="Model Name",type=string,JSONPath=`.spec.modelName`
 // +kubebuilder:printcolumn:name="Inference Pool",type=string,JSONPath=`.spec.poolRef.name`
 // +kubebuilder:printcolumn:name="Priority",type=string,JSONPath=`.spec.priority`
 // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
@@ -56,12 +55,6 @@ type InferenceObjectiveList struct {
 // performance and latency goals for the model. These workloads are
 // expected to operate within an InferencePool sharing compute capacity with other
 // InferenceObjectives, defined by the Inference Platform Admin.
-//
-// InferenceObjective's modelName (not the ObjectMeta name) is unique for a given InferencePool,
-// if the name is reused, an error will be shown on the status of a
-// InferenceObjective that attempted to reuse. The oldest InferenceObjective, based on
-// creation timestamp, will be selected to remain valid. In the event of a race
-// condition, one will be selected at random.
 type InferenceObjectiveSpec struct {
 
 	// Priority defines how important it is to serve the request compared to other requests in the same pool.
@@ -69,7 +62,7 @@ type InferenceObjectiveSpec struct {
 	// The higher the value, the more critical the request is; negative values _are_ allowed.
 	// No default value is set for this field, allowing for future additions of new fields that may 'one of' with this field.
 	// However, implementations that consume this field (such as the Endpoint Picker) will treat an unset value as '0'.
-	// Priority is used in flow control, primarily in the event of resource scarcity(reqeusts need to be queued).
+	// Priority is used in flow control, primarily in the event of resource scarcity(requests need to be queued).
 	// All requests will be queued, and flow control will _always_ allow requests of higher priority to be served first.
 	// Fairness is only enforced and tracked between requests of the same priority.
 	//
@@ -135,10 +128,6 @@ const (
 	//
 	// * "Accepted"
 	//
-	// Possible reasons for this condition to be False are:
-	//
-	// * "ModelNameInUse"
-	//
 	// Possible reasons for this condition to be Unknown are:
 	//
 	// * "Pending"
@@ -148,10 +137,6 @@ const (
 	// ObjectiveReasonAccepted is the desired state. Model conforms to the state of the pool.
 	ObjectiveReasonAccepted InferenceObjectiveConditionReason = "Accepted"
 
-	// ObjectiveReasonNameInUse is used when a given ModelName already exists within the pool.
-	// Details about naming conflict resolution are on the ModelName field itself.
-	ObjectiveReasonNameInUse InferenceObjectiveConditionReason = "ModelNameInUse"
-
 	// ObjectiveReasonPending is the initial state, and indicates that the controller has not yet reconciled the InferenceObjective.
 	ObjectiveReasonPending InferenceObjectiveConditionReason = "Pending"
 )
diff --git a/apix/v1alpha2/inferencepool_conversion.go b/apix/v1alpha2/inferencepool_conversion.go
index aa29d8f..01520dc 100644
--- a/apix/v1alpha2/inferencepool_conversion.go
+++ b/apix/v1alpha2/inferencepool_conversion.go
@@ -18,10 +18,9 @@ package v1alpha2
 
 import (
 	"errors"
-	"fmt"
 
-	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
-	runtime "k8s.io/apimachinery/pkg/runtime"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/utils/ptr"
 
 	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
 )
@@ -31,7 +30,7 @@ func (src *InferencePool) ConvertTo(dst *v1.InferencePool) error {
 	if dst == nil {
 		return errors.New("dst cannot be nil")
 	}
-	v1Extension, err := convertExtensionRefToV1(&src.Spec.ExtensionRef)
+	endpointPickRef, err := convertExtensionRefToV1(&src.Spec.ExtensionRef)
 	if err != nil {
 		return err
 	}
@@ -39,11 +38,17 @@ func (src *InferencePool) ConvertTo(dst *v1.InferencePool) error {
 	if err != nil {
 		return err
 	}
-	dst.TypeMeta = src.TypeMeta
+
+	meta := metav1.TypeMeta{
+		Kind:       src.Kind,
+		APIVersion: v1.GroupVersion.String(), // Ensure the API version is set correctly.
+	}
+	dst.TypeMeta = meta
 	dst.ObjectMeta = src.ObjectMeta
 	dst.Spec.TargetPorts = []v1.Port{{Number: v1.PortNumber(src.Spec.TargetPortNumber)}}
-	dst.Spec.ExtensionRef = v1Extension
+	dst.Spec.EndpointPickerRef = endpointPickRef
 	dst.Status = *v1Status
+
 	if src.Spec.Selector != nil {
 		dst.Spec.Selector.MatchLabels = make(map[v1.LabelKey]v1.LabelValue, len(src.Spec.Selector))
 		for k, v := range src.Spec.Selector {
@@ -58,7 +63,7 @@ func (dst *InferencePool) ConvertFrom(src *v1.InferencePool) error {
 	if src == nil {
 		return errors.New("src cannot be nil")
 	}
-	extensionRef, err := convertExtensionRefFromV1(&src.Spec.ExtensionRef)
+	extensionRef, err := convertEndpointPickerRefFromV1(&src.Spec.EndpointPickerRef)
 	if err != nil {
 		return err
 	}
@@ -66,11 +71,17 @@ func (dst *InferencePool) ConvertFrom(src *v1.InferencePool) error {
 	if err != nil {
 		return err
 	}
-	dst.TypeMeta = src.TypeMeta
+
+	meta := metav1.TypeMeta{
+		Kind:       src.Kind,
+		APIVersion: GroupVersion.String(), // Ensure the API version is set correctly.
+	}
+	dst.TypeMeta = meta
 	dst.ObjectMeta = src.ObjectMeta
 	dst.Spec.TargetPortNumber = int32(src.Spec.TargetPorts[0].Number)
 	dst.Spec.ExtensionRef = extensionRef
 	dst.Status = *status
+
 	if src.Spec.Selector.MatchLabels != nil {
 		dst.Spec.Selector = make(map[LabelKey]LabelValue, len(src.Spec.Selector.MatchLabels))
 		for k, v := range src.Spec.Selector.MatchLabels {
@@ -84,66 +95,191 @@ func convertStatusToV1(src *InferencePoolStatus) (*v1.InferencePoolStatus, error
 	if src == nil {
 		return nil, errors.New("src cannot be nil")
 	}
-	u, err := toUnstructured(src)
-	if err != nil {
-		return nil, err
+	if len(src.Parents) == 0 {
+		return &v1.InferencePoolStatus{}, nil
+	}
+	out := &v1.InferencePoolStatus{
+		Parents: make([]v1.ParentStatus, 0, len(src.Parents)),
+	}
+	for _, p := range src.Parents {
+		// Drop the synthetic "status/default" parent entirely.
+		if isV1Alpha2DefaultParent(p) {
+			continue
+		}
+		ps := v1.ParentStatus{
+			ParentRef:  toV1ParentRef(p.GatewayRef),
+			Conditions: nil, // start nil; only allocate if we actually keep any
+		}
+		for _, c := range p.Conditions {
+			// Drop the synthetic default condition.
+			if isV1Alpha2DefaultCondition(c) {
+				continue
+			}
+			cc := c
+			if cc.Type == string(v1.InferencePoolConditionAccepted) {
+				cc.Reason = mapAcceptedReasonToV1(cc.Reason)
+			}
+			ps.Conditions = append(ps.Conditions, cc)
+		}
+
+		// If no real conditions remain, leave nil (omitted in JSON).
+		out.Parents = append(out.Parents, ps)
 	}
-	return convert[v1.InferencePoolStatus](u)
+
+	// If all parents were synthetic and were dropped, normalize to empty status.
+	if len(out.Parents) == 0 {
+		return &v1.InferencePoolStatus{}, nil
+	}
+	return out, nil
 }
 
 func convertStatusFromV1(src *v1.InferencePoolStatus) (*InferencePoolStatus, error) {
 	if src == nil {
 		return nil, errors.New("src cannot be nil")
 	}
-	u, err := toUnstructured(src)
-	if err != nil {
-		return nil, err
+	if len(src.Parents) == 0 {
+		// Do not synthesize the default parent here; v1alpha2 CRD defaults cover creation-time,
+		// and conversion should reflect the true empty set.
+		return &InferencePoolStatus{}, nil
+	}
+	out := &InferencePoolStatus{
+		Parents: make([]PoolStatus, 0, len(src.Parents)),
+	}
+	for _, p := range src.Parents {
+		ps := PoolStatus{
+			GatewayRef: fromV1ParentRef(p.ParentRef),
+		}
+		if n := len(p.Conditions); n > 0 {
+			ps.Conditions = make([]metav1.Condition, 0, n)
+			for _, c := range p.Conditions {
+				cc := c
+				if cc.Type == string(v1.InferencePoolConditionAccepted) {
+					cc.Reason = mapAcceptedReasonFromV1(cc.Reason)
+				}
+				ps.Conditions = append(ps.Conditions, cc)
+			}
+		}
+		out.Parents = append(out.Parents, ps)
 	}
-	return convert[InferencePoolStatus](u)
+	return out, nil
 }
 
-func convertExtensionRefToV1(src *Extension) (v1.Extension, error) {
-	if src == nil {
-		return v1.Extension{}, errors.New("src cannot be nil")
+// isV1Alpha2DefaultParent returns true for the synthetic "no parents yet" entry.
+func isV1Alpha2DefaultParent(p PoolStatus) bool {
+	if p.GatewayRef.Kind == nil || p.GatewayRef.Name == "" {
+		return false
 	}
-	u, err := toUnstructured(src)
-	if err != nil {
-		return v1.Extension{}, err
+	return *p.GatewayRef.Kind == "Status" && p.GatewayRef.Name == "default"
+}
+
+// Map v1alpha2 -> v1 reasons for the "Accepted" condition.
+func mapAcceptedReasonToV1(r string) string {
+	switch InferencePoolReason(r) {
+	case InferencePoolReasonAccepted:
+		return string(v1.InferencePoolReasonAccepted)
+	case InferencePoolReasonNotSupportedByGateway:
+		return string(v1.InferencePoolReasonNotSupportedByParent)
+	default:
+		// Keep other reasons like "HTTPRouteNotAccepted" or "Pending" as-is.
+		return r
 	}
-	out, err := convert[v1.Extension](u)
-	if err != nil {
-		return v1.Extension{}, err
+}
+
+// Map v1 -> v1alpha2 reasons for the "Accepted" condition.
+func mapAcceptedReasonFromV1(r string) string {
+	switch v1.InferencePoolReason(r) {
+	case v1.InferencePoolReasonAccepted:
+		return string(InferencePoolReasonAccepted)
+	case v1.InferencePoolReasonNotSupportedByParent:
+		return string(InferencePoolReasonNotSupportedByGateway)
+	default:
+		return r
 	}
-	return *out, nil
 }
 
-func convertExtensionRefFromV1(src *v1.Extension) (Extension, error) {
-	if src == nil {
-		return Extension{}, errors.New("src cannot be nil")
+func isV1Alpha2DefaultCondition(c metav1.Condition) bool {
+	return InferencePoolConditionType(c.Type) == InferencePoolConditionAccepted &&
+		c.Status == metav1.ConditionUnknown &&
+		InferencePoolReason(c.Reason) == InferencePoolReasonPending
+}
+
+func toV1ParentRef(in ParentGatewayReference) v1.ParentReference {
+	out := v1.ParentReference{
+		Name: v1.ObjectName(in.Name),
 	}
-	u, err := toUnstructured(&src)
-	if err != nil {
-		return Extension{}, err
+	if in.Group != nil {
+		g := v1.Group(*in.Group)
+		out.Group = &g
 	}
-	extension, err := convert[Extension](u)
-	if err != nil {
-		return Extension{}, err
+	if in.Kind != nil {
+		k := v1.Kind(*in.Kind)
+		out.Kind = k
+	}
+	if in.Namespace != nil {
+		ns := v1.Namespace(*in.Namespace)
+		out.Namespace = ns
 	}
-	return *extension, nil
+	return out
 }
 
-func toUnstructured(obj any) (*unstructured.Unstructured, error) {
-	u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
-	if err != nil {
-		return nil, err
+func fromV1ParentRef(in v1.ParentReference) ParentGatewayReference {
+	out := ParentGatewayReference{
+		Name: ObjectName(in.Name),
+	}
+	if in.Group != nil {
+		g := Group(*in.Group)
+		out.Group = &g
+	}
+	if in.Kind != "" {
+		k := Kind(in.Kind)
+		out.Kind = &k
 	}
-	return &unstructured.Unstructured{Object: u}, nil
+	if in.Namespace != "" {
+		ns := Namespace(in.Namespace)
+		out.Namespace = &ns
+	}
+	return out
 }
 
-func convert[T any](u *unstructured.Unstructured) (*T, error) {
-	var res T
-	if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &res); err != nil {
-		return nil, fmt.Errorf("error converting unstructured to T: %v", err)
+func convertExtensionRefToV1(src *Extension) (v1.EndpointPickerRef, error) {
+	endpointPickerRef := v1.EndpointPickerRef{}
+	if src == nil {
+		return endpointPickerRef, errors.New("src cannot be nil")
+	}
+	if src.Group != nil {
+		endpointPickerRef.Group = ptr.To(v1.Group(*src.Group))
+	}
+	if src.Kind != nil {
+		endpointPickerRef.Kind = v1.Kind(*src.Kind)
+	}
+	endpointPickerRef.Name = v1.ObjectName(src.Name)
+	if src.PortNumber != nil {
+		endpointPickerRef.Port = ptr.To(v1.Port{Number: v1.PortNumber(*src.PortNumber)})
+	}
+	if src.FailureMode != nil {
+		endpointPickerRef.FailureMode = v1.EndpointPickerFailureMode(*src.FailureMode)
+	}
+
+	return endpointPickerRef, nil
+}
+
+func convertEndpointPickerRefFromV1(src *v1.EndpointPickerRef) (Extension, error) {
+	extension := Extension{}
+	if src == nil {
+		return extension, errors.New("src cannot be nil")
+	}
+	if src.Group != nil {
+		extension.Group = ptr.To(Group(*src.Group))
+	}
+	if src.Kind != "" {
+		extension.Kind = ptr.To(Kind(src.Kind))
+	}
+	extension.Name = ObjectName(src.Name)
+	if src.Port != nil {
+		extension.PortNumber = ptr.To(PortNumber(src.Port.Number))
+	}
+	if src.FailureMode != "" {
+		extension.FailureMode = ptr.To(ExtensionFailureMode(src.FailureMode))
 	}
-	return &res, nil
+	return extension, nil
 }
diff --git a/apix/v1alpha2/zz_generated.deepcopy.go b/apix/v1alpha2/zz_generated.deepcopy.go
index 5a71e75..0249d44 100644
--- a/apix/v1alpha2/zz_generated.deepcopy.go
+++ b/apix/v1alpha2/zz_generated.deepcopy.go
@@ -22,7 +22,7 @@ package v1alpha2
 
 import (
 	"k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
+	runtime "k8s.io/apimachinery/pkg/runtime"
 )
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
diff --git a/bbr.Dockerfile b/bbr.Dockerfile
index 8f21eea..1c294c4 100644
--- a/bbr.Dockerfile
+++ b/bbr.Dockerfile
@@ -1,6 +1,6 @@
 # Dockerfile has specific requirement to put this ARG at the beginning:
 # https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
-ARG BUILDER_IMAGE=golang:1.23
+ARG BUILDER_IMAGE=golang:1.24
 ARG BASE_IMAGE=gcr.io/distroless/static:nonroot
 
 ## Multistage build
@@ -18,6 +18,7 @@ RUN go mod download
 COPY cmd/bbr ./cmd
 COPY pkg ./pkg
 COPY internal ./internal
+COPY api ./api
 WORKDIR /src/cmd
 RUN go build -o /bbr
 
diff --git a/client-go/applyconfiguration/api/v1/extension.go b/client-go/applyconfiguration/api/v1/endpointpickerref.go
similarity index 57%
rename from client-go/applyconfiguration/api/v1/extension.go
rename to client-go/applyconfiguration/api/v1/endpointpickerref.go
index 7e7d645..0d78862 100644
--- a/client-go/applyconfiguration/api/v1/extension.go
+++ b/client-go/applyconfiguration/api/v1/endpointpickerref.go
@@ -22,26 +22,26 @@ import (
 	apiv1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
 )
 
-// ExtensionApplyConfiguration represents a declarative configuration of the Extension type for use
+// EndpointPickerRefApplyConfiguration represents a declarative configuration of the EndpointPickerRef type for use
 // with apply.
-type ExtensionApplyConfiguration struct {
-	Group       *apiv1.Group                `json:"group,omitempty"`
-	Kind        *apiv1.Kind                 `json:"kind,omitempty"`
-	Name        *apiv1.ObjectName           `json:"name,omitempty"`
-	PortNumber  *apiv1.PortNumber           `json:"portNumber,omitempty"`
-	FailureMode *apiv1.ExtensionFailureMode `json:"failureMode,omitempty"`
+type EndpointPickerRefApplyConfiguration struct {
+	Group       *apiv1.Group                     `json:"group,omitempty"`
+	Kind        *apiv1.Kind                      `json:"kind,omitempty"`
+	Name        *apiv1.ObjectName                `json:"name,omitempty"`
+	Port        *PortApplyConfiguration          `json:"port,omitempty"`
+	FailureMode *apiv1.EndpointPickerFailureMode `json:"failureMode,omitempty"`
 }
 
-// ExtensionApplyConfiguration constructs a declarative configuration of the Extension type for use with
+// EndpointPickerRefApplyConfiguration constructs a declarative configuration of the EndpointPickerRef type for use with
 // apply.
-func Extension() *ExtensionApplyConfiguration {
-	return &ExtensionApplyConfiguration{}
+func EndpointPickerRef() *EndpointPickerRefApplyConfiguration {
+	return &EndpointPickerRefApplyConfiguration{}
 }
 
 // WithGroup sets the Group field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Group field is set to the value of the last call.
-func (b *ExtensionApplyConfiguration) WithGroup(value apiv1.Group) *ExtensionApplyConfiguration {
+func (b *EndpointPickerRefApplyConfiguration) WithGroup(value apiv1.Group) *EndpointPickerRefApplyConfiguration {
 	b.Group = &value
 	return b
 }
@@ -49,7 +49,7 @@ func (b *ExtensionApplyConfiguration) WithGroup(value apiv1.Group) *ExtensionApp
 // WithKind sets the Kind field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Kind field is set to the value of the last call.
-func (b *ExtensionApplyConfiguration) WithKind(value apiv1.Kind) *ExtensionApplyConfiguration {
+func (b *EndpointPickerRefApplyConfiguration) WithKind(value apiv1.Kind) *EndpointPickerRefApplyConfiguration {
 	b.Kind = &value
 	return b
 }
@@ -57,23 +57,23 @@ func (b *ExtensionApplyConfiguration) WithKind(value apiv1.Kind) *ExtensionApply
 // WithName sets the Name field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Name field is set to the value of the last call.
-func (b *ExtensionApplyConfiguration) WithName(value apiv1.ObjectName) *ExtensionApplyConfiguration {
+func (b *EndpointPickerRefApplyConfiguration) WithName(value apiv1.ObjectName) *EndpointPickerRefApplyConfiguration {
 	b.Name = &value
 	return b
 }
 
-// WithPortNumber sets the PortNumber field in the declarative configuration to the given value
+// WithPort sets the Port field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the PortNumber field is set to the value of the last call.
-func (b *ExtensionApplyConfiguration) WithPortNumber(value apiv1.PortNumber) *ExtensionApplyConfiguration {
-	b.PortNumber = &value
+// If called multiple times, the Port field is set to the value of the last call.
+func (b *EndpointPickerRefApplyConfiguration) WithPort(value *PortApplyConfiguration) *EndpointPickerRefApplyConfiguration {
+	b.Port = value
 	return b
 }
 
 // WithFailureMode sets the FailureMode field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the FailureMode field is set to the value of the last call.
-func (b *ExtensionApplyConfiguration) WithFailureMode(value apiv1.ExtensionFailureMode) *ExtensionApplyConfiguration {
+func (b *EndpointPickerRefApplyConfiguration) WithFailureMode(value apiv1.EndpointPickerFailureMode) *EndpointPickerRefApplyConfiguration {
 	b.FailureMode = &value
 	return b
 }
diff --git a/client-go/applyconfiguration/api/v1/inferencepool.go b/client-go/applyconfiguration/api/v1/inferencepool.go
index eaea68c..d62f1c3 100644
--- a/client-go/applyconfiguration/api/v1/inferencepool.go
+++ b/client-go/applyconfiguration/api/v1/inferencepool.go
@@ -43,6 +43,7 @@ func InferencePool(name, namespace string) *InferencePoolApplyConfiguration {
 	b.WithAPIVersion("inference.networking.k8s.io/v1")
 	return b
 }
+func (b InferencePoolApplyConfiguration) IsApplyConfiguration() {}
 
 // WithKind sets the Kind field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
@@ -218,8 +219,24 @@ func (b *InferencePoolApplyConfiguration) WithStatus(value *InferencePoolStatusA
 	return b
 }
 
+// GetKind retrieves the value of the Kind field in the declarative configuration.
+func (b *InferencePoolApplyConfiguration) GetKind() *string {
+	return b.TypeMetaApplyConfiguration.Kind
+}
+
+// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
+func (b *InferencePoolApplyConfiguration) GetAPIVersion() *string {
+	return b.TypeMetaApplyConfiguration.APIVersion
+}
+
 // GetName retrieves the value of the Name field in the declarative configuration.
 func (b *InferencePoolApplyConfiguration) GetName() *string {
 	b.ensureObjectMetaApplyConfigurationExists()
 	return b.ObjectMetaApplyConfiguration.Name
 }
+
+// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
+func (b *InferencePoolApplyConfiguration) GetNamespace() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Namespace
+}
diff --git a/client-go/applyconfiguration/api/v1/inferencepoolspec.go b/client-go/applyconfiguration/api/v1/inferencepoolspec.go
index 364d059..ca44987 100644
--- a/client-go/applyconfiguration/api/v1/inferencepoolspec.go
+++ b/client-go/applyconfiguration/api/v1/inferencepoolspec.go
@@ -21,9 +21,9 @@ package v1
 // InferencePoolSpecApplyConfiguration represents a declarative configuration of the InferencePoolSpec type for use
 // with apply.
 type InferencePoolSpecApplyConfiguration struct {
-	Selector     *LabelSelectorApplyConfiguration `json:"selector,omitempty"`
-	TargetPorts  []PortApplyConfiguration         `json:"targetPorts,omitempty"`
-	ExtensionRef *ExtensionApplyConfiguration     `json:"extensionRef,omitempty"`
+	Selector          *LabelSelectorApplyConfiguration     `json:"selector,omitempty"`
+	TargetPorts       []PortApplyConfiguration             `json:"targetPorts,omitempty"`
+	EndpointPickerRef *EndpointPickerRefApplyConfiguration `json:"endpointPickerRef,omitempty"`
 }
 
 // InferencePoolSpecApplyConfiguration constructs a declarative configuration of the InferencePoolSpec type for use with
@@ -53,10 +53,10 @@ func (b *InferencePoolSpecApplyConfiguration) WithTargetPorts(values ...*PortApp
 	return b
 }
 
-// WithExtensionRef sets the ExtensionRef field in the declarative configuration to the given value
+// WithEndpointPickerRef sets the EndpointPickerRef field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the ExtensionRef field is set to the value of the last call.
-func (b *InferencePoolSpecApplyConfiguration) WithExtensionRef(value *ExtensionApplyConfiguration) *InferencePoolSpecApplyConfiguration {
-	b.ExtensionRef = value
+// If called multiple times, the EndpointPickerRef field is set to the value of the last call.
+func (b *InferencePoolSpecApplyConfiguration) WithEndpointPickerRef(value *EndpointPickerRefApplyConfiguration) *InferencePoolSpecApplyConfiguration {
+	b.EndpointPickerRef = value
 	return b
 }
diff --git a/client-go/applyconfiguration/api/v1/inferencepoolstatus.go b/client-go/applyconfiguration/api/v1/inferencepoolstatus.go
index 5c66e34..499b771 100644
--- a/client-go/applyconfiguration/api/v1/inferencepoolstatus.go
+++ b/client-go/applyconfiguration/api/v1/inferencepoolstatus.go
@@ -21,7 +21,7 @@ package v1
 // InferencePoolStatusApplyConfiguration represents a declarative configuration of the InferencePoolStatus type for use
 // with apply.
 type InferencePoolStatusApplyConfiguration struct {
-	Parents []PoolStatusApplyConfiguration `json:"parent,omitempty"`
+	Parents []ParentStatusApplyConfiguration `json:"parents,omitempty"`
 }
 
 // InferencePoolStatusApplyConfiguration constructs a declarative configuration of the InferencePoolStatus type for use with
@@ -33,7 +33,7 @@ func InferencePoolStatus() *InferencePoolStatusApplyConfiguration {
 // WithParents adds the given value to the Parents field in the declarative configuration
 // and returns the receiver, so that objects can be build by chaining "With" function invocations.
 // If called multiple times, values provided by each call will be appended to the Parents field.
-func (b *InferencePoolStatusApplyConfiguration) WithParents(values ...*PoolStatusApplyConfiguration) *InferencePoolStatusApplyConfiguration {
+func (b *InferencePoolStatusApplyConfiguration) WithParents(values ...*ParentStatusApplyConfiguration) *InferencePoolStatusApplyConfiguration {
 	for i := range values {
 		if values[i] == nil {
 			panic("nil value passed to WithParents")
diff --git a/client-go/applyconfiguration/api/v1/parentgatewayreference.go b/client-go/applyconfiguration/api/v1/parentreference.go
similarity index 69%
rename from client-go/applyconfiguration/api/v1/parentgatewayreference.go
rename to client-go/applyconfiguration/api/v1/parentreference.go
index 5e23aeb..2798f02 100644
--- a/client-go/applyconfiguration/api/v1/parentgatewayreference.go
+++ b/client-go/applyconfiguration/api/v1/parentreference.go
@@ -22,25 +22,25 @@ import (
 	apiv1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
 )
 
-// ParentGatewayReferenceApplyConfiguration represents a declarative configuration of the ParentGatewayReference type for use
+// ParentReferenceApplyConfiguration represents a declarative configuration of the ParentReference type for use
 // with apply.
-type ParentGatewayReferenceApplyConfiguration struct {
+type ParentReferenceApplyConfiguration struct {
 	Group     *apiv1.Group      `json:"group,omitempty"`
 	Kind      *apiv1.Kind       `json:"kind,omitempty"`
 	Name      *apiv1.ObjectName `json:"name,omitempty"`
 	Namespace *apiv1.Namespace  `json:"namespace,omitempty"`
 }
 
-// ParentGatewayReferenceApplyConfiguration constructs a declarative configuration of the ParentGatewayReference type for use with
+// ParentReferenceApplyConfiguration constructs a declarative configuration of the ParentReference type for use with
 // apply.
-func ParentGatewayReference() *ParentGatewayReferenceApplyConfiguration {
-	return &ParentGatewayReferenceApplyConfiguration{}
+func ParentReference() *ParentReferenceApplyConfiguration {
+	return &ParentReferenceApplyConfiguration{}
 }
 
 // WithGroup sets the Group field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Group field is set to the value of the last call.
-func (b *ParentGatewayReferenceApplyConfiguration) WithGroup(value apiv1.Group) *ParentGatewayReferenceApplyConfiguration {
+func (b *ParentReferenceApplyConfiguration) WithGroup(value apiv1.Group) *ParentReferenceApplyConfiguration {
 	b.Group = &value
 	return b
 }
@@ -48,7 +48,7 @@ func (b *ParentGatewayReferenceApplyConfiguration) WithGroup(value apiv1.Group)
 // WithKind sets the Kind field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Kind field is set to the value of the last call.
-func (b *ParentGatewayReferenceApplyConfiguration) WithKind(value apiv1.Kind) *ParentGatewayReferenceApplyConfiguration {
+func (b *ParentReferenceApplyConfiguration) WithKind(value apiv1.Kind) *ParentReferenceApplyConfiguration {
 	b.Kind = &value
 	return b
 }
@@ -56,7 +56,7 @@ func (b *ParentGatewayReferenceApplyConfiguration) WithKind(value apiv1.Kind) *P
 // WithName sets the Name field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Name field is set to the value of the last call.
-func (b *ParentGatewayReferenceApplyConfiguration) WithName(value apiv1.ObjectName) *ParentGatewayReferenceApplyConfiguration {
+func (b *ParentReferenceApplyConfiguration) WithName(value apiv1.ObjectName) *ParentReferenceApplyConfiguration {
 	b.Name = &value
 	return b
 }
@@ -64,7 +64,7 @@ func (b *ParentGatewayReferenceApplyConfiguration) WithName(value apiv1.ObjectNa
 // WithNamespace sets the Namespace field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Namespace field is set to the value of the last call.
-func (b *ParentGatewayReferenceApplyConfiguration) WithNamespace(value apiv1.Namespace) *ParentGatewayReferenceApplyConfiguration {
+func (b *ParentReferenceApplyConfiguration) WithNamespace(value apiv1.Namespace) *ParentReferenceApplyConfiguration {
 	b.Namespace = &value
 	return b
 }
diff --git a/client-go/applyconfiguration/api/v1/parentstatus.go b/client-go/applyconfiguration/api/v1/parentstatus.go
new file mode 100644
index 0000000..929df58
--- /dev/null
+++ b/client-go/applyconfiguration/api/v1/parentstatus.go
@@ -0,0 +1,67 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1
+
+import (
+	metav1 "k8s.io/client-go/applyconfigurations/meta/v1"
+	apiv1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+)
+
+// ParentStatusApplyConfiguration represents a declarative configuration of the ParentStatus type for use
+// with apply.
+type ParentStatusApplyConfiguration struct {
+	Conditions     []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"`
+	ParentRef      *ParentReferenceApplyConfiguration   `json:"parentRef,omitempty"`
+	ControllerName *apiv1.ControllerName                `json:"controllerName,omitempty"`
+}
+
+// ParentStatusApplyConfiguration constructs a declarative configuration of the ParentStatus type for use with
+// apply.
+func ParentStatus() *ParentStatusApplyConfiguration {
+	return &ParentStatusApplyConfiguration{}
+}
+
+// WithConditions adds the given value to the Conditions field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the Conditions field.
+func (b *ParentStatusApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *ParentStatusApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithConditions")
+		}
+		b.Conditions = append(b.Conditions, *values[i])
+	}
+	return b
+}
+
+// WithParentRef sets the ParentRef field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the ParentRef field is set to the value of the last call.
+func (b *ParentStatusApplyConfiguration) WithParentRef(value *ParentReferenceApplyConfiguration) *ParentStatusApplyConfiguration {
+	b.ParentRef = value
+	return b
+}
+
+// WithControllerName sets the ControllerName field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the ControllerName field is set to the value of the last call.
+func (b *ParentStatusApplyConfiguration) WithControllerName(value apiv1.ControllerName) *ParentStatusApplyConfiguration {
+	b.ControllerName = &value
+	return b
+}
diff --git a/client-go/applyconfiguration/api/v1/poolstatus.go b/client-go/applyconfiguration/api/v1/poolstatus.go
deleted file mode 100644
index 6c582d8..0000000
--- a/client-go/applyconfiguration/api/v1/poolstatus.go
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Copyright The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by applyconfiguration-gen. DO NOT EDIT.
-
-package v1
-
-import (
-	metav1 "k8s.io/client-go/applyconfigurations/meta/v1"
-)
-
-// PoolStatusApplyConfiguration represents a declarative configuration of the PoolStatus type for use
-// with apply.
-type PoolStatusApplyConfiguration struct {
-	Conditions []metav1.ConditionApplyConfiguration      `json:"conditions,omitempty"`
-	GatewayRef *ParentGatewayReferenceApplyConfiguration `json:"parentRef,omitempty"`
-}
-
-// PoolStatusApplyConfiguration constructs a declarative configuration of the PoolStatus type for use with
-// apply.
-func PoolStatus() *PoolStatusApplyConfiguration {
-	return &PoolStatusApplyConfiguration{}
-}
-
-// WithConditions adds the given value to the Conditions field in the declarative configuration
-// and returns the receiver, so that objects can be build by chaining "With" function invocations.
-// If called multiple times, values provided by each call will be appended to the Conditions field.
-func (b *PoolStatusApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *PoolStatusApplyConfiguration {
-	for i := range values {
-		if values[i] == nil {
-			panic("nil value passed to WithConditions")
-		}
-		b.Conditions = append(b.Conditions, *values[i])
-	}
-	return b
-}
-
-// WithGatewayRef sets the GatewayRef field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the GatewayRef field is set to the value of the last call.
-func (b *PoolStatusApplyConfiguration) WithGatewayRef(value *ParentGatewayReferenceApplyConfiguration) *PoolStatusApplyConfiguration {
-	b.GatewayRef = value
-	return b
-}
diff --git a/client-go/applyconfiguration/apix/v1alpha1/exportingcluster.go b/client-go/applyconfiguration/apix/v1alpha1/exportingcluster.go
new file mode 100644
index 0000000..d1b2db0
--- /dev/null
+++ b/client-go/applyconfiguration/apix/v1alpha1/exportingcluster.go
@@ -0,0 +1,43 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	apixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
+)
+
+// ExportingClusterApplyConfiguration represents a declarative configuration of the ExportingCluster type for use
+// with apply.
+type ExportingClusterApplyConfiguration struct {
+	Name *apixv1alpha1.ClusterName `json:"name,omitempty"`
+}
+
+// ExportingClusterApplyConfiguration constructs a declarative configuration of the ExportingCluster type for use with
+// apply.
+func ExportingCluster() *ExportingClusterApplyConfiguration {
+	return &ExportingClusterApplyConfiguration{}
+}
+
+// WithName sets the Name field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Name field is set to the value of the last call.
+func (b *ExportingClusterApplyConfiguration) WithName(value apixv1alpha1.ClusterName) *ExportingClusterApplyConfiguration {
+	b.Name = &value
+	return b
+}
diff --git a/client-go/applyconfiguration/apix/v1alpha1/importcontroller.go b/client-go/applyconfiguration/apix/v1alpha1/importcontroller.go
new file mode 100644
index 0000000..1c30787
--- /dev/null
+++ b/client-go/applyconfiguration/apix/v1alpha1/importcontroller.go
@@ -0,0 +1,87 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	metav1 "k8s.io/client-go/applyconfigurations/meta/v1"
+	apixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
+	v1 "sigs.k8s.io/gateway-api-inference-extension/client-go/applyconfiguration/api/v1"
+)
+
+// ImportControllerApplyConfiguration represents a declarative configuration of the ImportController type for use
+// with apply.
+type ImportControllerApplyConfiguration struct {
+	Name              *apixv1alpha1.ControllerName         `json:"name,omitempty"`
+	ExportingClusters []ExportingClusterApplyConfiguration `json:"exportingClusters,omitempty"`
+	Parents           []v1.ParentStatusApplyConfiguration  `json:"parents,omitempty"`
+	Conditions        []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"`
+}
+
+// ImportControllerApplyConfiguration constructs a declarative configuration of the ImportController type for use with
+// apply.
+func ImportController() *ImportControllerApplyConfiguration {
+	return &ImportControllerApplyConfiguration{}
+}
+
+// WithName sets the Name field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Name field is set to the value of the last call.
+func (b *ImportControllerApplyConfiguration) WithName(value apixv1alpha1.ControllerName) *ImportControllerApplyConfiguration {
+	b.Name = &value
+	return b
+}
+
+// WithExportingClusters adds the given value to the ExportingClusters field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the ExportingClusters field.
+func (b *ImportControllerApplyConfiguration) WithExportingClusters(values ...*ExportingClusterApplyConfiguration) *ImportControllerApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithExportingClusters")
+		}
+		b.ExportingClusters = append(b.ExportingClusters, *values[i])
+	}
+	return b
+}
+
+// WithParents adds the given value to the Parents field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the Parents field.
+func (b *ImportControllerApplyConfiguration) WithParents(values ...*v1.ParentStatusApplyConfiguration) *ImportControllerApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithParents")
+		}
+		b.Parents = append(b.Parents, *values[i])
+	}
+	return b
+}
+
+// WithConditions adds the given value to the Conditions field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the Conditions field.
+func (b *ImportControllerApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *ImportControllerApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithConditions")
+		}
+		b.Conditions = append(b.Conditions, *values[i])
+	}
+	return b
+}
diff --git a/client-go/applyconfiguration/apix/v1alpha1/inferencepoolimport.go b/client-go/applyconfiguration/apix/v1alpha1/inferencepoolimport.go
new file mode 100644
index 0000000..f29c038
--- /dev/null
+++ b/client-go/applyconfiguration/apix/v1alpha1/inferencepoolimport.go
@@ -0,0 +1,233 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	types "k8s.io/apimachinery/pkg/types"
+	v1 "k8s.io/client-go/applyconfigurations/meta/v1"
+)
+
+// InferencePoolImportApplyConfiguration represents a declarative configuration of the InferencePoolImport type for use
+// with apply.
+type InferencePoolImportApplyConfiguration struct {
+	v1.TypeMetaApplyConfiguration    `json:",inline"`
+	*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
+	Status                           *InferencePoolImportStatusApplyConfiguration `json:"status,omitempty"`
+}
+
+// InferencePoolImport constructs a declarative configuration of the InferencePoolImport type for use with
+// apply.
+func InferencePoolImport(name, namespace string) *InferencePoolImportApplyConfiguration {
+	b := &InferencePoolImportApplyConfiguration{}
+	b.WithName(name)
+	b.WithNamespace(namespace)
+	b.WithKind("InferencePoolImport")
+	b.WithAPIVersion("inference.networking.x-k8s.io/v1alpha1")
+	return b
+}
+func (b InferencePoolImportApplyConfiguration) IsApplyConfiguration() {}
+
+// WithKind sets the Kind field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Kind field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithKind(value string) *InferencePoolImportApplyConfiguration {
+	b.TypeMetaApplyConfiguration.Kind = &value
+	return b
+}
+
+// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the APIVersion field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithAPIVersion(value string) *InferencePoolImportApplyConfiguration {
+	b.TypeMetaApplyConfiguration.APIVersion = &value
+	return b
+}
+
+// WithName sets the Name field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Name field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithName(value string) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.Name = &value
+	return b
+}
+
+// WithGenerateName sets the GenerateName field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the GenerateName field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithGenerateName(value string) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.GenerateName = &value
+	return b
+}
+
+// WithNamespace sets the Namespace field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Namespace field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithNamespace(value string) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.Namespace = &value
+	return b
+}
+
+// WithUID sets the UID field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the UID field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithUID(value types.UID) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.UID = &value
+	return b
+}
+
+// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the ResourceVersion field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithResourceVersion(value string) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.ResourceVersion = &value
+	return b
+}
+
+// WithGeneration sets the Generation field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Generation field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithGeneration(value int64) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.Generation = &value
+	return b
+}
+
+// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the CreationTimestamp field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithCreationTimestamp(value metav1.Time) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
+	return b
+}
+
+// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the DeletionTimestamp field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
+	return b
+}
+
+// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
+	return b
+}
+
+// WithLabels puts the entries into the Labels field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, the entries provided by each call will be put on the Labels field,
+// overwriting an existing map entries in Labels field with the same key.
+func (b *InferencePoolImportApplyConfiguration) WithLabels(entries map[string]string) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
+		b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
+	}
+	for k, v := range entries {
+		b.ObjectMetaApplyConfiguration.Labels[k] = v
+	}
+	return b
+}
+
+// WithAnnotations puts the entries into the Annotations field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, the entries provided by each call will be put on the Annotations field,
+// overwriting an existing map entries in Annotations field with the same key.
+func (b *InferencePoolImportApplyConfiguration) WithAnnotations(entries map[string]string) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
+		b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
+	}
+	for k, v := range entries {
+		b.ObjectMetaApplyConfiguration.Annotations[k] = v
+	}
+	return b
+}
+
+// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the OwnerReferences field.
+func (b *InferencePoolImportApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithOwnerReferences")
+		}
+		b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
+	}
+	return b
+}
+
+// WithFinalizers adds the given value to the Finalizers field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the Finalizers field.
+func (b *InferencePoolImportApplyConfiguration) WithFinalizers(values ...string) *InferencePoolImportApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	for i := range values {
+		b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
+	}
+	return b
+}
+
+func (b *InferencePoolImportApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
+	if b.ObjectMetaApplyConfiguration == nil {
+		b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{}
+	}
+}
+
+// WithStatus sets the Status field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Status field is set to the value of the last call.
+func (b *InferencePoolImportApplyConfiguration) WithStatus(value *InferencePoolImportStatusApplyConfiguration) *InferencePoolImportApplyConfiguration {
+	b.Status = value
+	return b
+}
+
+// GetKind retrieves the value of the Kind field in the declarative configuration.
+func (b *InferencePoolImportApplyConfiguration) GetKind() *string {
+	return b.TypeMetaApplyConfiguration.Kind
+}
+
+// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
+func (b *InferencePoolImportApplyConfiguration) GetAPIVersion() *string {
+	return b.TypeMetaApplyConfiguration.APIVersion
+}
+
+// GetName retrieves the value of the Name field in the declarative configuration.
+func (b *InferencePoolImportApplyConfiguration) GetName() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Name
+}
+
+// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
+func (b *InferencePoolImportApplyConfiguration) GetNamespace() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Namespace
+}
diff --git a/client-go/applyconfiguration/apix/v1alpha1/inferencepoolimportstatus.go b/client-go/applyconfiguration/apix/v1alpha1/inferencepoolimportstatus.go
new file mode 100644
index 0000000..9c21414
--- /dev/null
+++ b/client-go/applyconfiguration/apix/v1alpha1/inferencepoolimportstatus.go
@@ -0,0 +1,44 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1alpha1
+
+// InferencePoolImportStatusApplyConfiguration represents a declarative configuration of the InferencePoolImportStatus type for use
+// with apply.
+type InferencePoolImportStatusApplyConfiguration struct {
+	Controllers []ImportControllerApplyConfiguration `json:"controllers,omitempty"`
+}
+
+// InferencePoolImportStatusApplyConfiguration constructs a declarative configuration of the InferencePoolImportStatus type for use with
+// apply.
+func InferencePoolImportStatus() *InferencePoolImportStatusApplyConfiguration {
+	return &InferencePoolImportStatusApplyConfiguration{}
+}
+
+// WithControllers adds the given value to the Controllers field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the Controllers field.
+func (b *InferencePoolImportStatusApplyConfiguration) WithControllers(values ...*ImportControllerApplyConfiguration) *InferencePoolImportStatusApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithControllers")
+		}
+		b.Controllers = append(b.Controllers, *values[i])
+	}
+	return b
+}
diff --git a/client-go/applyconfiguration/apix/v1alpha2/inferenceobjective.go b/client-go/applyconfiguration/apix/v1alpha2/inferenceobjective.go
index bc244db..e23a5d6 100644
--- a/client-go/applyconfiguration/apix/v1alpha2/inferenceobjective.go
+++ b/client-go/applyconfiguration/apix/v1alpha2/inferenceobjective.go
@@ -43,6 +43,7 @@ func InferenceObjective(name, namespace string) *InferenceObjectiveApplyConfigur
 	b.WithAPIVersion("inference.networking.x-k8s.io/v1alpha2")
 	return b
 }
+func (b InferenceObjectiveApplyConfiguration) IsApplyConfiguration() {}
 
 // WithKind sets the Kind field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
@@ -218,8 +219,24 @@ func (b *InferenceObjectiveApplyConfiguration) WithStatus(value *InferenceObject
 	return b
 }
 
+// GetKind retrieves the value of the Kind field in the declarative configuration.
+func (b *InferenceObjectiveApplyConfiguration) GetKind() *string {
+	return b.TypeMetaApplyConfiguration.Kind
+}
+
+// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
+func (b *InferenceObjectiveApplyConfiguration) GetAPIVersion() *string {
+	return b.TypeMetaApplyConfiguration.APIVersion
+}
+
 // GetName retrieves the value of the Name field in the declarative configuration.
 func (b *InferenceObjectiveApplyConfiguration) GetName() *string {
 	b.ensureObjectMetaApplyConfigurationExists()
 	return b.ObjectMetaApplyConfiguration.Name
 }
+
+// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
+func (b *InferenceObjectiveApplyConfiguration) GetNamespace() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Namespace
+}
diff --git a/client-go/applyconfiguration/apix/v1alpha2/inferencepool.go b/client-go/applyconfiguration/apix/v1alpha2/inferencepool.go
index 8cbd4e5..3b1c622 100644
--- a/client-go/applyconfiguration/apix/v1alpha2/inferencepool.go
+++ b/client-go/applyconfiguration/apix/v1alpha2/inferencepool.go
@@ -43,6 +43,7 @@ func InferencePool(name, namespace string) *InferencePoolApplyConfiguration {
 	b.WithAPIVersion("inference.networking.x-k8s.io/v1alpha2")
 	return b
 }
+func (b InferencePoolApplyConfiguration) IsApplyConfiguration() {}
 
 // WithKind sets the Kind field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
@@ -218,8 +219,24 @@ func (b *InferencePoolApplyConfiguration) WithStatus(value *InferencePoolStatusA
 	return b
 }
 
+// GetKind retrieves the value of the Kind field in the declarative configuration.
+func (b *InferencePoolApplyConfiguration) GetKind() *string {
+	return b.TypeMetaApplyConfiguration.Kind
+}
+
+// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
+func (b *InferencePoolApplyConfiguration) GetAPIVersion() *string {
+	return b.TypeMetaApplyConfiguration.APIVersion
+}
+
 // GetName retrieves the value of the Name field in the declarative configuration.
 func (b *InferencePoolApplyConfiguration) GetName() *string {
 	b.ensureObjectMetaApplyConfigurationExists()
 	return b.ObjectMetaApplyConfiguration.Name
 }
+
+// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
+func (b *InferencePoolApplyConfiguration) GetNamespace() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Namespace
+}
diff --git a/client-go/applyconfiguration/internal/internal.go b/client-go/applyconfiguration/internal/internal.go
index 1064e22..c482faa 100644
--- a/client-go/applyconfiguration/internal/internal.go
+++ b/client-go/applyconfiguration/internal/internal.go
@@ -22,7 +22,7 @@ import (
 	fmt "fmt"
 	sync "sync"
 
-	typed "sigs.k8s.io/structured-merge-diff/v4/typed"
+	typed "sigs.k8s.io/structured-merge-diff/v6/typed"
 )
 
 func Parser() *typed.Parser {
diff --git a/client-go/applyconfiguration/utils.go b/client-go/applyconfiguration/utils.go
index c5d4f57..7e4ea09 100644
--- a/client-go/applyconfiguration/utils.go
+++ b/client-go/applyconfiguration/utils.go
@@ -21,10 +21,12 @@ package applyconfiguration
 import (
 	runtime "k8s.io/apimachinery/pkg/runtime"
 	schema "k8s.io/apimachinery/pkg/runtime/schema"
-	testing "k8s.io/client-go/testing"
+	managedfields "k8s.io/apimachinery/pkg/util/managedfields"
 	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+	v1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
 	v1alpha2 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
 	apiv1 "sigs.k8s.io/gateway-api-inference-extension/client-go/applyconfiguration/api/v1"
+	apixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/applyconfiguration/apix/v1alpha1"
 	apixv1alpha2 "sigs.k8s.io/gateway-api-inference-extension/client-go/applyconfiguration/apix/v1alpha2"
 	internal "sigs.k8s.io/gateway-api-inference-extension/client-go/applyconfiguration/internal"
 )
@@ -34,8 +36,8 @@ import (
 func ForKind(kind schema.GroupVersionKind) interface{} {
 	switch kind {
 	// Group=inference.networking.k8s.io, Version=v1
-	case v1.SchemeGroupVersion.WithKind("Extension"):
-		return &apiv1.ExtensionApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("EndpointPickerRef"):
+		return &apiv1.EndpointPickerRefApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("InferencePool"):
 		return &apiv1.InferencePoolApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("InferencePoolSpec"):
@@ -44,13 +46,23 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		return &apiv1.InferencePoolStatusApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("LabelSelector"):
 		return &apiv1.LabelSelectorApplyConfiguration{}
-	case v1.SchemeGroupVersion.WithKind("ParentGatewayReference"):
-		return &apiv1.ParentGatewayReferenceApplyConfiguration{}
-	case v1.SchemeGroupVersion.WithKind("PoolStatus"):
-		return &apiv1.PoolStatusApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("ParentReference"):
+		return &apiv1.ParentReferenceApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("ParentStatus"):
+		return &apiv1.ParentStatusApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("Port"):
 		return &apiv1.PortApplyConfiguration{}
 
+		// Group=inference.networking.x-k8s.io, Version=v1alpha1
+	case v1alpha1.SchemeGroupVersion.WithKind("ExportingCluster"):
+		return &apixv1alpha1.ExportingClusterApplyConfiguration{}
+	case v1alpha1.SchemeGroupVersion.WithKind("ImportController"):
+		return &apixv1alpha1.ImportControllerApplyConfiguration{}
+	case v1alpha1.SchemeGroupVersion.WithKind("InferencePoolImport"):
+		return &apixv1alpha1.InferencePoolImportApplyConfiguration{}
+	case v1alpha1.SchemeGroupVersion.WithKind("InferencePoolImportStatus"):
+		return &apixv1alpha1.InferencePoolImportStatusApplyConfiguration{}
+
 		// Group=inference.networking.x-k8s.io, Version=v1alpha2
 	case v1alpha2.SchemeGroupVersion.WithKind("Extension"):
 		return &apixv1alpha2.ExtensionApplyConfiguration{}
@@ -77,6 +89,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 	return nil
 }
 
-func NewTypeConverter(scheme *runtime.Scheme) *testing.TypeConverter {
-	return &testing.TypeConverter{Scheme: scheme, TypeResolver: internal.Parser()}
+func NewTypeConverter(scheme *runtime.Scheme) managedfields.TypeConverter {
+	return managedfields.NewSchemeTypeConverter(scheme, internal.Parser())
 }
diff --git a/client-go/clientset/versioned/clientset.go b/client-go/clientset/versioned/clientset.go
index 928ab89..0ea4a00 100644
--- a/client-go/clientset/versioned/clientset.go
+++ b/client-go/clientset/versioned/clientset.go
@@ -26,12 +26,14 @@ import (
 	rest "k8s.io/client-go/rest"
 	flowcontrol "k8s.io/client-go/util/flowcontrol"
 	inferencev1 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/api/v1"
+	inferencev1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/apix/v1alpha1"
 	xinferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/apix/v1alpha2"
 )
 
 type Interface interface {
 	Discovery() discovery.DiscoveryInterface
 	InferenceV1() inferencev1.InferenceV1Interface
+	InferenceV1alpha1() inferencev1alpha1.InferenceV1alpha1Interface
 	XInferenceV1alpha2() xinferencev1alpha2.XInferenceV1alpha2Interface
 }
 
@@ -39,6 +41,7 @@ type Interface interface {
 type Clientset struct {
 	*discovery.DiscoveryClient
 	inferenceV1        *inferencev1.InferenceV1Client
+	inferenceV1alpha1  *inferencev1alpha1.InferenceV1alpha1Client
 	xInferenceV1alpha2 *xinferencev1alpha2.XInferenceV1alpha2Client
 }
 
@@ -47,6 +50,11 @@ func (c *Clientset) InferenceV1() inferencev1.InferenceV1Interface {
 	return c.inferenceV1
 }
 
+// InferenceV1alpha1 retrieves the InferenceV1alpha1Client
+func (c *Clientset) InferenceV1alpha1() inferencev1alpha1.InferenceV1alpha1Interface {
+	return c.inferenceV1alpha1
+}
+
 // XInferenceV1alpha2 retrieves the XInferenceV1alpha2Client
 func (c *Clientset) XInferenceV1alpha2() xinferencev1alpha2.XInferenceV1alpha2Interface {
 	return c.xInferenceV1alpha2
@@ -100,6 +108,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset,
 	if err != nil {
 		return nil, err
 	}
+	cs.inferenceV1alpha1, err = inferencev1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient)
+	if err != nil {
+		return nil, err
+	}
 	cs.xInferenceV1alpha2, err = xinferencev1alpha2.NewForConfigAndClient(&configShallowCopy, httpClient)
 	if err != nil {
 		return nil, err
@@ -126,6 +138,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
 func New(c rest.Interface) *Clientset {
 	var cs Clientset
 	cs.inferenceV1 = inferencev1.New(c)
+	cs.inferenceV1alpha1 = inferencev1alpha1.New(c)
 	cs.xInferenceV1alpha2 = xinferencev1alpha2.New(c)
 
 	cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
diff --git a/client-go/clientset/versioned/fake/clientset_generated.go b/client-go/clientset/versioned/fake/clientset_generated.go
index 5a40059..baa42d8 100644
--- a/client-go/clientset/versioned/fake/clientset_generated.go
+++ b/client-go/clientset/versioned/fake/clientset_generated.go
@@ -29,6 +29,8 @@ import (
 	clientset "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned"
 	inferencev1 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/api/v1"
 	fakeinferencev1 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/api/v1/fake"
+	inferencev1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/apix/v1alpha1"
+	fakeinferencev1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/apix/v1alpha1/fake"
 	xinferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/apix/v1alpha2"
 	fakexinferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/apix/v1alpha2/fake"
 )
@@ -107,8 +109,8 @@ func NewClientset(objects ...runtime.Object) *Clientset {
 	cs.AddReactor("*", "*", testing.ObjectReaction(o))
 	cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
 		var opts metav1.ListOptions
-		if watchActcion, ok := action.(testing.WatchActionImpl); ok {
-			opts = watchActcion.ListOptions
+		if watchAction, ok := action.(testing.WatchActionImpl); ok {
+			opts = watchAction.ListOptions
 		}
 		gvr := action.GetResource()
 		ns := action.GetNamespace()
@@ -132,6 +134,11 @@ func (c *Clientset) InferenceV1() inferencev1.InferenceV1Interface {
 	return &fakeinferencev1.FakeInferenceV1{Fake: &c.Fake}
 }
 
+// InferenceV1alpha1 retrieves the InferenceV1alpha1Client
+func (c *Clientset) InferenceV1alpha1() inferencev1alpha1.InferenceV1alpha1Interface {
+	return &fakeinferencev1alpha1.FakeInferenceV1alpha1{Fake: &c.Fake}
+}
+
 // XInferenceV1alpha2 retrieves the XInferenceV1alpha2Client
 func (c *Clientset) XInferenceV1alpha2() xinferencev1alpha2.XInferenceV1alpha2Interface {
 	return &fakexinferencev1alpha2.FakeXInferenceV1alpha2{Fake: &c.Fake}
diff --git a/client-go/clientset/versioned/fake/register.go b/client-go/clientset/versioned/fake/register.go
index 5c6d338..412308d 100644
--- a/client-go/clientset/versioned/fake/register.go
+++ b/client-go/clientset/versioned/fake/register.go
@@ -25,6 +25,7 @@ import (
 	serializer "k8s.io/apimachinery/pkg/runtime/serializer"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 	inferencev1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+	inferencev1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
 	xinferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
 )
 
@@ -33,6 +34,7 @@ var codecs = serializer.NewCodecFactory(scheme)
 
 var localSchemeBuilder = runtime.SchemeBuilder{
 	inferencev1.AddToScheme,
+	inferencev1alpha1.AddToScheme,
 	xinferencev1alpha2.AddToScheme,
 }
 
diff --git a/client-go/clientset/versioned/scheme/register.go b/client-go/clientset/versioned/scheme/register.go
index 7836df4..47bdc7c 100644
--- a/client-go/clientset/versioned/scheme/register.go
+++ b/client-go/clientset/versioned/scheme/register.go
@@ -25,6 +25,7 @@ import (
 	serializer "k8s.io/apimachinery/pkg/runtime/serializer"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 	inferencev1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+	inferencev1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
 	xinferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
 )
 
@@ -33,6 +34,7 @@ var Codecs = serializer.NewCodecFactory(Scheme)
 var ParameterCodec = runtime.NewParameterCodec(Scheme)
 var localSchemeBuilder = runtime.SchemeBuilder{
 	inferencev1.AddToScheme,
+	inferencev1alpha1.AddToScheme,
 	xinferencev1alpha2.AddToScheme,
 }
 
diff --git a/client-go/clientset/versioned/typed/apix/v1alpha1/apix_client.go b/client-go/clientset/versioned/typed/apix/v1alpha1/apix_client.go
new file mode 100644
index 0000000..726c410
--- /dev/null
+++ b/client-go/clientset/versioned/typed/apix/v1alpha1/apix_client.go
@@ -0,0 +1,101 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	http "net/http"
+
+	rest "k8s.io/client-go/rest"
+	apixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
+	scheme "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/scheme"
+)
+
+type InferenceV1alpha1Interface interface {
+	RESTClient() rest.Interface
+	InferencePoolImportsGetter
+}
+
+// InferenceV1alpha1Client is used to interact with features provided by the inference.networking.x-k8s.io group.
+type InferenceV1alpha1Client struct {
+	restClient rest.Interface
+}
+
+func (c *InferenceV1alpha1Client) InferencePoolImports(namespace string) InferencePoolImportInterface {
+	return newInferencePoolImports(c, namespace)
+}
+
+// NewForConfig creates a new InferenceV1alpha1Client for the given config.
+// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
+// where httpClient was generated with rest.HTTPClientFor(c).
+func NewForConfig(c *rest.Config) (*InferenceV1alpha1Client, error) {
+	config := *c
+	setConfigDefaults(&config)
+	httpClient, err := rest.HTTPClientFor(&config)
+	if err != nil {
+		return nil, err
+	}
+	return NewForConfigAndClient(&config, httpClient)
+}
+
+// NewForConfigAndClient creates a new InferenceV1alpha1Client for the given config and http client.
+// Note the http client provided takes precedence over the configured transport values.
+func NewForConfigAndClient(c *rest.Config, h *http.Client) (*InferenceV1alpha1Client, error) {
+	config := *c
+	setConfigDefaults(&config)
+	client, err := rest.RESTClientForConfigAndClient(&config, h)
+	if err != nil {
+		return nil, err
+	}
+	return &InferenceV1alpha1Client{client}, nil
+}
+
+// NewForConfigOrDie creates a new InferenceV1alpha1Client for the given config and
+// panics if there is an error in the config.
+func NewForConfigOrDie(c *rest.Config) *InferenceV1alpha1Client {
+	client, err := NewForConfig(c)
+	if err != nil {
+		panic(err)
+	}
+	return client
+}
+
+// New creates a new InferenceV1alpha1Client for the given RESTClient.
+func New(c rest.Interface) *InferenceV1alpha1Client {
+	return &InferenceV1alpha1Client{c}
+}
+
+func setConfigDefaults(config *rest.Config) {
+	gv := apixv1alpha1.SchemeGroupVersion
+	config.GroupVersion = &gv
+	config.APIPath = "/apis"
+	config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion()
+
+	if config.UserAgent == "" {
+		config.UserAgent = rest.DefaultKubernetesUserAgent()
+	}
+}
+
+// RESTClient returns a RESTClient that is used to communicate
+// with API server by this client implementation.
+func (c *InferenceV1alpha1Client) RESTClient() rest.Interface {
+	if c == nil {
+		return nil
+	}
+	return c.restClient
+}
diff --git a/client-go/clientset/versioned/typed/apix/v1alpha1/doc.go b/client-go/clientset/versioned/typed/apix/v1alpha1/doc.go
new file mode 100644
index 0000000..df51baa
--- /dev/null
+++ b/client-go/clientset/versioned/typed/apix/v1alpha1/doc.go
@@ -0,0 +1,20 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+// This package has the automatically generated typed clients.
+package v1alpha1
diff --git a/client-go/clientset/versioned/typed/apix/v1alpha1/fake/doc.go b/client-go/clientset/versioned/typed/apix/v1alpha1/fake/doc.go
new file mode 100644
index 0000000..16f4439
--- /dev/null
+++ b/client-go/clientset/versioned/typed/apix/v1alpha1/fake/doc.go
@@ -0,0 +1,20 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+// Package fake has the automatically generated clients.
+package fake
diff --git a/client-go/clientset/versioned/typed/apix/v1alpha1/fake/fake_apix_client.go b/client-go/clientset/versioned/typed/apix/v1alpha1/fake/fake_apix_client.go
new file mode 100644
index 0000000..1de7688
--- /dev/null
+++ b/client-go/clientset/versioned/typed/apix/v1alpha1/fake/fake_apix_client.go
@@ -0,0 +1,40 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+	rest "k8s.io/client-go/rest"
+	testing "k8s.io/client-go/testing"
+	v1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/apix/v1alpha1"
+)
+
+type FakeInferenceV1alpha1 struct {
+	*testing.Fake
+}
+
+func (c *FakeInferenceV1alpha1) InferencePoolImports(namespace string) v1alpha1.InferencePoolImportInterface {
+	return newFakeInferencePoolImports(c, namespace)
+}
+
+// RESTClient returns a RESTClient that is used to communicate
+// with API server by this client implementation.
+func (c *FakeInferenceV1alpha1) RESTClient() rest.Interface {
+	var ret *rest.RESTClient
+	return ret
+}
diff --git a/client-go/clientset/versioned/typed/apix/v1alpha1/fake/fake_inferencepoolimport.go b/client-go/clientset/versioned/typed/apix/v1alpha1/fake/fake_inferencepoolimport.go
new file mode 100644
index 0000000..7a6938f
--- /dev/null
+++ b/client-go/clientset/versioned/typed/apix/v1alpha1/fake/fake_inferencepoolimport.go
@@ -0,0 +1,53 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+	gentype "k8s.io/client-go/gentype"
+	v1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
+	apixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/applyconfiguration/apix/v1alpha1"
+	typedapixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/typed/apix/v1alpha1"
+)
+
+// fakeInferencePoolImports implements InferencePoolImportInterface
+type fakeInferencePoolImports struct {
+	*gentype.FakeClientWithListAndApply[*v1alpha1.InferencePoolImport, *v1alpha1.InferencePoolImportList, *apixv1alpha1.InferencePoolImportApplyConfiguration]
+	Fake *FakeInferenceV1alpha1
+}
+
+func newFakeInferencePoolImports(fake *FakeInferenceV1alpha1, namespace string) typedapixv1alpha1.InferencePoolImportInterface {
+	return &fakeInferencePoolImports{
+		gentype.NewFakeClientWithListAndApply[*v1alpha1.InferencePoolImport, *v1alpha1.InferencePoolImportList, *apixv1alpha1.InferencePoolImportApplyConfiguration](
+			fake.Fake,
+			namespace,
+			v1alpha1.SchemeGroupVersion.WithResource("inferencepoolimports"),
+			v1alpha1.SchemeGroupVersion.WithKind("InferencePoolImport"),
+			func() *v1alpha1.InferencePoolImport { return &v1alpha1.InferencePoolImport{} },
+			func() *v1alpha1.InferencePoolImportList { return &v1alpha1.InferencePoolImportList{} },
+			func(dst, src *v1alpha1.InferencePoolImportList) { dst.ListMeta = src.ListMeta },
+			func(list *v1alpha1.InferencePoolImportList) []*v1alpha1.InferencePoolImport {
+				return gentype.ToPointerSlice(list.Items)
+			},
+			func(list *v1alpha1.InferencePoolImportList, items []*v1alpha1.InferencePoolImport) {
+				list.Items = gentype.FromPointerSlice(items)
+			},
+		),
+		fake,
+	}
+}
diff --git a/client-go/clientset/versioned/typed/apix/v1alpha1/generated_expansion.go b/client-go/clientset/versioned/typed/apix/v1alpha1/generated_expansion.go
new file mode 100644
index 0000000..0969f5b
--- /dev/null
+++ b/client-go/clientset/versioned/typed/apix/v1alpha1/generated_expansion.go
@@ -0,0 +1,21 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1alpha1
+
+type InferencePoolImportExpansion interface{}
diff --git a/client-go/clientset/versioned/typed/apix/v1alpha1/inferencepoolimport.go b/client-go/clientset/versioned/typed/apix/v1alpha1/inferencepoolimport.go
new file mode 100644
index 0000000..f68766d
--- /dev/null
+++ b/client-go/clientset/versioned/typed/apix/v1alpha1/inferencepoolimport.go
@@ -0,0 +1,74 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	context "context"
+
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	types "k8s.io/apimachinery/pkg/types"
+	watch "k8s.io/apimachinery/pkg/watch"
+	gentype "k8s.io/client-go/gentype"
+	apixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
+	applyconfigurationapixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/applyconfiguration/apix/v1alpha1"
+	scheme "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned/scheme"
+)
+
+// InferencePoolImportsGetter has a method to return a InferencePoolImportInterface.
+// A group's client should implement this interface.
+type InferencePoolImportsGetter interface {
+	InferencePoolImports(namespace string) InferencePoolImportInterface
+}
+
+// InferencePoolImportInterface has methods to work with InferencePoolImport resources.
+type InferencePoolImportInterface interface {
+	Create(ctx context.Context, inferencePoolImport *apixv1alpha1.InferencePoolImport, opts v1.CreateOptions) (*apixv1alpha1.InferencePoolImport, error)
+	Update(ctx context.Context, inferencePoolImport *apixv1alpha1.InferencePoolImport, opts v1.UpdateOptions) (*apixv1alpha1.InferencePoolImport, error)
+	// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+	UpdateStatus(ctx context.Context, inferencePoolImport *apixv1alpha1.InferencePoolImport, opts v1.UpdateOptions) (*apixv1alpha1.InferencePoolImport, error)
+	Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
+	DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
+	Get(ctx context.Context, name string, opts v1.GetOptions) (*apixv1alpha1.InferencePoolImport, error)
+	List(ctx context.Context, opts v1.ListOptions) (*apixv1alpha1.InferencePoolImportList, error)
+	Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
+	Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *apixv1alpha1.InferencePoolImport, err error)
+	Apply(ctx context.Context, inferencePoolImport *applyconfigurationapixv1alpha1.InferencePoolImportApplyConfiguration, opts v1.ApplyOptions) (result *apixv1alpha1.InferencePoolImport, err error)
+	// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus().
+	ApplyStatus(ctx context.Context, inferencePoolImport *applyconfigurationapixv1alpha1.InferencePoolImportApplyConfiguration, opts v1.ApplyOptions) (result *apixv1alpha1.InferencePoolImport, err error)
+	InferencePoolImportExpansion
+}
+
+// inferencePoolImports implements InferencePoolImportInterface
+type inferencePoolImports struct {
+	*gentype.ClientWithListAndApply[*apixv1alpha1.InferencePoolImport, *apixv1alpha1.InferencePoolImportList, *applyconfigurationapixv1alpha1.InferencePoolImportApplyConfiguration]
+}
+
+// newInferencePoolImports returns a InferencePoolImports
+func newInferencePoolImports(c *InferenceV1alpha1Client, namespace string) *inferencePoolImports {
+	return &inferencePoolImports{
+		gentype.NewClientWithListAndApply[*apixv1alpha1.InferencePoolImport, *apixv1alpha1.InferencePoolImportList, *applyconfigurationapixv1alpha1.InferencePoolImportApplyConfiguration](
+			"inferencepoolimports",
+			c.RESTClient(),
+			scheme.ParameterCodec,
+			namespace,
+			func() *apixv1alpha1.InferencePoolImport { return &apixv1alpha1.InferencePoolImport{} },
+			func() *apixv1alpha1.InferencePoolImportList { return &apixv1alpha1.InferencePoolImportList{} },
+		),
+	}
+}
diff --git a/client-go/informers/externalversions/apix/interface.go b/client-go/informers/externalversions/apix/interface.go
index 26e1817..426cbcd 100644
--- a/client-go/informers/externalversions/apix/interface.go
+++ b/client-go/informers/externalversions/apix/interface.go
@@ -19,12 +19,15 @@ limitations under the License.
 package apix
 
 import (
+	v1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/informers/externalversions/apix/v1alpha1"
 	v1alpha2 "sigs.k8s.io/gateway-api-inference-extension/client-go/informers/externalversions/apix/v1alpha2"
 	internalinterfaces "sigs.k8s.io/gateway-api-inference-extension/client-go/informers/externalversions/internalinterfaces"
 )
 
 // Interface provides access to each of this group's versions.
 type Interface interface {
+	// V1alpha1 provides access to shared informers for resources in V1alpha1.
+	V1alpha1() v1alpha1.Interface
 	// V1alpha2 provides access to shared informers for resources in V1alpha2.
 	V1alpha2() v1alpha2.Interface
 }
@@ -40,6 +43,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
 	return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
 }
 
+// V1alpha1 returns a new v1alpha1.Interface.
+func (g *group) V1alpha1() v1alpha1.Interface {
+	return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
+}
+
 // V1alpha2 returns a new v1alpha2.Interface.
 func (g *group) V1alpha2() v1alpha2.Interface {
 	return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions)
diff --git a/client-go/informers/externalversions/apix/v1alpha1/inferencepoolimport.go b/client-go/informers/externalversions/apix/v1alpha1/inferencepoolimport.go
new file mode 100644
index 0000000..9013e02
--- /dev/null
+++ b/client-go/informers/externalversions/apix/v1alpha1/inferencepoolimport.go
@@ -0,0 +1,102 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	context "context"
+	time "time"
+
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+	watch "k8s.io/apimachinery/pkg/watch"
+	cache "k8s.io/client-go/tools/cache"
+	gatewayapiinferenceextensionapixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
+	versioned "sigs.k8s.io/gateway-api-inference-extension/client-go/clientset/versioned"
+	internalinterfaces "sigs.k8s.io/gateway-api-inference-extension/client-go/informers/externalversions/internalinterfaces"
+	apixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/client-go/listers/apix/v1alpha1"
+)
+
+// InferencePoolImportInformer provides access to a shared informer and lister for
+// InferencePoolImports.
+type InferencePoolImportInformer interface {
+	Informer() cache.SharedIndexInformer
+	Lister() apixv1alpha1.InferencePoolImportLister
+}
+
+type inferencePoolImportInformer struct {
+	factory          internalinterfaces.SharedInformerFactory
+	tweakListOptions internalinterfaces.TweakListOptionsFunc
+	namespace        string
+}
+
+// NewInferencePoolImportInformer constructs a new informer for InferencePoolImport type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewInferencePoolImportInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+	return NewFilteredInferencePoolImportInformer(client, namespace, resyncPeriod, indexers, nil)
+}
+
+// NewFilteredInferencePoolImportInformer constructs a new informer for InferencePoolImport type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewFilteredInferencePoolImportInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+	return cache.NewSharedIndexInformer(
+		&cache.ListWatch{
+			ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.InferenceV1alpha1().InferencePoolImports(namespace).List(context.Background(), options)
+			},
+			WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.InferenceV1alpha1().InferencePoolImports(namespace).Watch(context.Background(), options)
+			},
+			ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.InferenceV1alpha1().InferencePoolImports(namespace).List(ctx, options)
+			},
+			WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.InferenceV1alpha1().InferencePoolImports(namespace).Watch(ctx, options)
+			},
+		},
+		&gatewayapiinferenceextensionapixv1alpha1.InferencePoolImport{},
+		resyncPeriod,
+		indexers,
+	)
+}
+
+func (f *inferencePoolImportInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+	return NewFilteredInferencePoolImportInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+}
+
+func (f *inferencePoolImportInformer) Informer() cache.SharedIndexInformer {
+	return f.factory.InformerFor(&gatewayapiinferenceextensionapixv1alpha1.InferencePoolImport{}, f.defaultInformer)
+}
+
+func (f *inferencePoolImportInformer) Lister() apixv1alpha1.InferencePoolImportLister {
+	return apixv1alpha1.NewInferencePoolImportLister(f.Informer().GetIndexer())
+}
diff --git a/client-go/informers/externalversions/apix/v1alpha1/interface.go b/client-go/informers/externalversions/apix/v1alpha1/interface.go
new file mode 100644
index 0000000..50e84d5
--- /dev/null
+++ b/client-go/informers/externalversions/apix/v1alpha1/interface.go
@@ -0,0 +1,45 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	internalinterfaces "sigs.k8s.io/gateway-api-inference-extension/client-go/informers/externalversions/internalinterfaces"
+)
+
+// Interface provides access to all the informers in this group version.
+type Interface interface {
+	// InferencePoolImports returns a InferencePoolImportInformer.
+	InferencePoolImports() InferencePoolImportInformer
+}
+
+type version struct {
+	factory          internalinterfaces.SharedInformerFactory
+	namespace        string
+	tweakListOptions internalinterfaces.TweakListOptionsFunc
+}
+
+// New returns a new Interface.
+func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
+	return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
+}
+
+// InferencePoolImports returns a InferencePoolImportInformer.
+func (v *version) InferencePoolImports() InferencePoolImportInformer {
+	return &inferencePoolImportInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
+}
diff --git a/client-go/informers/externalversions/generic.go b/client-go/informers/externalversions/generic.go
index 03c95ee..2fe2915 100644
--- a/client-go/informers/externalversions/generic.go
+++ b/client-go/informers/externalversions/generic.go
@@ -24,6 +24,7 @@ import (
 	schema "k8s.io/apimachinery/pkg/runtime/schema"
 	cache "k8s.io/client-go/tools/cache"
 	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+	v1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
 	v1alpha2 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
 )
 
@@ -57,6 +58,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
 	case v1.SchemeGroupVersion.WithResource("inferencepools"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Inference().V1().InferencePools().Informer()}, nil
 
+		// Group=inference.networking.x-k8s.io, Version=v1alpha1
+	case v1alpha1.SchemeGroupVersion.WithResource("inferencepoolimports"):
+		return &genericInformer{resource: resource.GroupResource(), informer: f.XInference().V1alpha1().InferencePoolImports().Informer()}, nil
+
 		// Group=inference.networking.x-k8s.io, Version=v1alpha2
 	case v1alpha2.SchemeGroupVersion.WithResource("inferenceobjectives"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.XInference().V1alpha2().InferenceObjectives().Informer()}, nil
diff --git a/client-go/listers/apix/v1alpha1/expansion_generated.go b/client-go/listers/apix/v1alpha1/expansion_generated.go
new file mode 100644
index 0000000..7c0d32c
--- /dev/null
+++ b/client-go/listers/apix/v1alpha1/expansion_generated.go
@@ -0,0 +1,27 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1alpha1
+
+// InferencePoolImportListerExpansion allows custom methods to be added to
+// InferencePoolImportLister.
+type InferencePoolImportListerExpansion interface{}
+
+// InferencePoolImportNamespaceListerExpansion allows custom methods to be added to
+// InferencePoolImportNamespaceLister.
+type InferencePoolImportNamespaceListerExpansion interface{}
diff --git a/client-go/listers/apix/v1alpha1/inferencepoolimport.go b/client-go/listers/apix/v1alpha1/inferencepoolimport.go
new file mode 100644
index 0000000..653bbfa
--- /dev/null
+++ b/client-go/listers/apix/v1alpha1/inferencepoolimport.go
@@ -0,0 +1,70 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	labels "k8s.io/apimachinery/pkg/labels"
+	listers "k8s.io/client-go/listers"
+	cache "k8s.io/client-go/tools/cache"
+	apixv1alpha1 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1"
+)
+
+// InferencePoolImportLister helps list InferencePoolImports.
+// All objects returned here must be treated as read-only.
+type InferencePoolImportLister interface {
+	// List lists all InferencePoolImports in the indexer.
+	// Objects returned here must be treated as read-only.
+	List(selector labels.Selector) (ret []*apixv1alpha1.InferencePoolImport, err error)
+	// InferencePoolImports returns an object that can list and get InferencePoolImports.
+	InferencePoolImports(namespace string) InferencePoolImportNamespaceLister
+	InferencePoolImportListerExpansion
+}
+
+// inferencePoolImportLister implements the InferencePoolImportLister interface.
+type inferencePoolImportLister struct {
+	listers.ResourceIndexer[*apixv1alpha1.InferencePoolImport]
+}
+
+// NewInferencePoolImportLister returns a new InferencePoolImportLister.
+func NewInferencePoolImportLister(indexer cache.Indexer) InferencePoolImportLister {
+	return &inferencePoolImportLister{listers.New[*apixv1alpha1.InferencePoolImport](indexer, apixv1alpha1.Resource("inferencepoolimport"))}
+}
+
+// InferencePoolImports returns an object that can list and get InferencePoolImports.
+func (s *inferencePoolImportLister) InferencePoolImports(namespace string) InferencePoolImportNamespaceLister {
+	return inferencePoolImportNamespaceLister{listers.NewNamespaced[*apixv1alpha1.InferencePoolImport](s.ResourceIndexer, namespace)}
+}
+
+// InferencePoolImportNamespaceLister helps list and get InferencePoolImports.
+// All objects returned here must be treated as read-only.
+type InferencePoolImportNamespaceLister interface {
+	// List lists all InferencePoolImports in the indexer for a given namespace.
+	// Objects returned here must be treated as read-only.
+	List(selector labels.Selector) (ret []*apixv1alpha1.InferencePoolImport, err error)
+	// Get retrieves the InferencePoolImport from the indexer for a given namespace and name.
+	// Objects returned here must be treated as read-only.
+	Get(name string) (*apixv1alpha1.InferencePoolImport, error)
+	InferencePoolImportNamespaceListerExpansion
+}
+
+// inferencePoolImportNamespaceLister implements the InferencePoolImportNamespaceLister
+// interface.
+type inferencePoolImportNamespaceLister struct {
+	listers.ResourceIndexer[*apixv1alpha1.InferencePoolImport]
+}
diff --git a/cmd/epp/runner/health.go b/cmd/epp/runner/health.go
index 6e63e17..1edbcff 100644
--- a/cmd/epp/runner/health.go
+++ b/cmd/epp/runner/health.go
@@ -65,7 +65,12 @@ func (s *healthServer) Check(ctx context.Context, in *healthPb.HealthCheckReques
 	case ReadinessCheckService:
 		checkName = "readiness"
 		isPassing = isLive && s.isLeader.Load()
-	case LivenessCheckService, "": // Default to liveness check if service is empty
+	case "": // Handle overall server health for load balancers that use an empty service name.
+		checkName = "empty service name (considered as overall health)"
+		// The overall health for a load balancer should reflect readiness to accept traffic,
+		// which is true only for the leader pod that has synced its data.
+		isPassing = isLive && s.isLeader.Load()
+	case LivenessCheckService:
 		checkName = "liveness"
 		// Any pod that is running and can respond to this gRPC check is considered "live".
 		// The datastore sync status should not affect liveness, only readiness.
diff --git a/cmd/epp/runner/runner.go b/cmd/epp/runner/runner.go
index eb2ea3b..2842704 100644
--- a/cmd/epp/runner/runner.go
+++ b/cmd/epp/runner/runner.go
@@ -25,6 +25,7 @@ import (
 	"net/http"
 	"net/http/pprof"
 	"os"
+	"runtime"
 	"sync/atomic"
 
 	"github.com/go-logr/logr"
@@ -46,6 +47,8 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/common"
 	backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/config/loader"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datalayer"
+	dlmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datalayer/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datastore"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metrics/collectors"
@@ -59,103 +62,50 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/scorer"
 	testfilter "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/test/filter"
 	runserver "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/server"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/env"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
 	"sigs.k8s.io/gateway-api-inference-extension/version"
 )
 
+const (
+	// enableExperimentalDatalayerV2 defines the environment variable
+	// used as feature flag for the pluggable data layer.
+	enableExperimentalDatalayerV2 = "ENABLE_EXPERIMENTAL_DATALAYER_V2"
+)
+
 var (
-	grpcPort = flag.Int(
-		"grpc-port",
-		runserver.DefaultGrpcPort,
-		"The gRPC port used for communicating with Envoy proxy")
-	grpcHealthPort = flag.Int(
-		"grpc-health-port",
-		runserver.DefaultGrpcHealthPort,
-		"The port used for gRPC liveness and readiness probes")
-	metricsPort = flag.Int(
-		"metrics-port",
-		runserver.DefaultMetricsPort,
-		"The metrics port")
-	enablePprof = flag.Bool(
-		"enable-pprof",
-		runserver.DefaultEnablePprof,
-		"Enables pprof handlers. Defaults to true. Set to false to disable pprof handlers.")
-	poolName = flag.String(
-		"pool-name",
-		runserver.DefaultPoolName,
-		"Name of the InferencePool this Endpoint Picker is associated with.")
-	poolGroup = flag.String(
-		"pool-group",
-		runserver.DefaultPoolGroup,
-		"group of the InferencePool this Endpoint Picker is associated with.")
-	poolNamespace = flag.String(
-		"pool-namespace",
-		runserver.DefaultPoolNamespace,
-		"Namespace of the InferencePool this Endpoint Picker is associated with.")
-	logVerbosity = flag.Int(
-		"v",
-		logging.DEFAULT,
-		"number for the log level verbosity")
-	secureServing = flag.Bool(
-		"secure-serving",
-		runserver.DefaultSecureServing,
-		"Enables secure serving. Defaults to true.")
-	healthChecking = flag.Bool(
-		"health-checking",
-		runserver.DefaultHealthChecking,
-		"Enables health checking")
-	certPath = flag.String(
-		"cert-path",
-		runserver.DefaultCertPath,
-		"The path to the certificate for secure serving. The certificate and private key files "+
-			"are assumed to be named tls.crt and tls.key, respectively. If not set, and secureServing is enabled, "+
-			"then a self-signed certificate is used.")
+	grpcPort       = flag.Int("grpc-port", runserver.DefaultGrpcPort, "The gRPC port used for communicating with Envoy proxy")
+	grpcHealthPort = flag.Int("grpc-health-port", runserver.DefaultGrpcHealthPort, "The port used for gRPC liveness and readiness probes")
+	metricsPort    = flag.Int("metrics-port", runserver.DefaultMetricsPort, "The metrics port")
+	enablePprof    = flag.Bool("enable-pprof", runserver.DefaultEnablePprof, "Enables pprof handlers. Defaults to true. Set to false to disable pprof handlers.")
+	poolName       = flag.String("pool-name", runserver.DefaultPoolName, "Name of the InferencePool this Endpoint Picker is associated with.")
+	poolGroup      = flag.String("pool-group", runserver.DefaultPoolGroup, "group of the InferencePool this Endpoint Picker is associated with.")
+	poolNamespace  = flag.String("pool-namespace", "", "Namespace of the InferencePool this Endpoint Picker is associated with.")
+	logVerbosity   = flag.Int("v", logging.DEFAULT, "number for the log level verbosity")
+	secureServing  = flag.Bool("secure-serving", runserver.DefaultSecureServing, "Enables secure serving. Defaults to true.")
+	healthChecking = flag.Bool("health-checking", runserver.DefaultHealthChecking, "Enables health checking")
+	certPath       = flag.String("cert-path", runserver.DefaultCertPath, "The path to the certificate for secure serving. The certificate and private key files "+
+		"are assumed to be named tls.crt and tls.key, respectively. If not set, and secureServing is enabled, "+
+		"then a self-signed certificate is used.")
 	// metric flags
-	totalQueuedRequestsMetric = flag.String(
-		"total-queued-requests-metric",
-		runserver.DefaultTotalQueuedRequestsMetric,
-		"Prometheus metric for the number of queued requests.")
-	kvCacheUsagePercentageMetric = flag.String(
-		"kv-cache-usage-percentage-metric",
-		runserver.DefaultKvCacheUsagePercentageMetric,
-		"Prometheus metric for the fraction of KV-cache blocks currently in use (from 0 to 1).")
+	totalQueuedRequestsMetric    = flag.String("total-queued-requests-metric", runserver.DefaultTotalQueuedRequestsMetric, "Prometheus metric for the number of queued requests.")
+	kvCacheUsagePercentageMetric = flag.String("kv-cache-usage-percentage-metric", runserver.DefaultKvCacheUsagePercentageMetric, "Prometheus metric for the fraction of KV-cache blocks currently in use (from 0 to 1).")
 	// LoRA metrics
-	loraInfoMetric = flag.String(
-		"lora-info-metric",
-		runserver.DefaultLoraInfoMetric,
-		"Prometheus metric for the LoRA info metrics (must be in vLLM label format).")
-
+	loraInfoMetric = flag.String("lora-info-metric", runserver.DefaultLoraInfoMetric, "Prometheus metric for the LoRA info metrics (must be in vLLM label format).")
 	// metrics related flags
-	refreshMetricsInterval = flag.Duration(
-		"refresh-metrics-interval",
-		runserver.DefaultRefreshMetricsInterval,
-		"interval to refresh metrics")
-	refreshPrometheusMetricsInterval = flag.Duration(
-		"refresh-prometheus-metrics-interval",
-		runserver.DefaultRefreshPrometheusMetricsInterval,
-		"interval to flush prometheus metrics")
-	metricsStalenessThreshold = flag.Duration("metrics-staleness-threshold",
-		runserver.DefaultMetricsStalenessThreshold,
-		"Duration after which metrics are considered stale. This is used to determine if a pod's metrics are fresh enough.")
+	refreshMetricsInterval           = flag.Duration("refresh-metrics-interval", runserver.DefaultRefreshMetricsInterval, "interval to refresh metrics")
+	refreshPrometheusMetricsInterval = flag.Duration("refresh-prometheus-metrics-interval", runserver.DefaultRefreshPrometheusMetricsInterval, "interval to flush prometheus metrics")
+	metricsStalenessThreshold        = flag.Duration("metrics-staleness-threshold", runserver.DefaultMetricsStalenessThreshold, "Duration after which metrics are considered stale. This is used to determine if a pod's metrics are fresh enough.")
 	// configuration flags
-	configFile = flag.String(
-		"config-file",
-		runserver.DefaultConfigFile,
-		"The path to the configuration file")
-	configText = flag.String(
-		"config-text",
-		runserver.DefaultConfigText,
-		"The configuration specified as text, in lieu of a file")
+	configFile = flag.String("config-file", runserver.DefaultConfigFile, "The path to the configuration file")
+	configText = flag.String("config-text", runserver.DefaultConfigText, "The configuration specified as text, in lieu of a file")
 
 	modelServerMetricsPort = flag.Int("model-server-metrics-port", 0, "Port to scrape metrics from pods. "+
 		"Default value will be set to the InferencePool.Spec.TargetPorts[0].Number if not set.")
 	modelServerMetricsPath                    = flag.String("model-server-metrics-path", "/metrics", "Path to scrape metrics from pods")
 	modelServerMetricsScheme                  = flag.String("model-server-metrics-scheme", "http", "Scheme to scrape metrics from pods")
 	modelServerMetricsHttpsInsecureSkipVerify = flag.Bool("model-server-metrics-https-insecure-skip-verify", true, "When using 'https' scheme for 'model-server-metrics-scheme', configure 'InsecureSkipVerify' (default to true)")
-	haEnableLeaderElection                    = flag.Bool(
-		"ha-enable-leader-election",
-		false,
-		"Enables leader election for high availability. When enabled, readiness probes will only pass on the leader.")
+	haEnableLeaderElection                    = flag.Bool("ha-enable-leader-election", false, "Enables leader election for high availability. When enabled, readiness probes will only pass on the leader.")
 
 	setupLog = ctrl.Log.WithName("setup")
 )
@@ -183,35 +133,7 @@ func (r *Runner) WithSchedulerConfig(schedulerConfig *scheduling.SchedulerConfig
 	return r
 }
 
-func bindEnvToFlags() {
-	// map[ENV_VAR]flagName   – add more as needed
-	for env, flg := range map[string]string{
-		"GRPC_PORT":                                       "grpc-port",
-		"GRPC_HEALTH_PORT":                                "grpc-health-port",
-		"MODEL_SERVER_METRICS_PORT":                       "model-server-metrics-port",
-		"MODEL_SERVER_METRICS_PATH":                       "model-server-metrics-path",
-		"MODEL_SERVER_METRICS_SCHEME":                     "model-server-metrics-scheme",
-		"MODEL_SERVER_METRICS_HTTPS_INSECURE_SKIP_VERIFY": "model-server-metrics-https-insecure-skip-verify",
-		"POOL_NAME":                                       "pool-name",
-		"POOL_NAMESPACE":                                  "pool-namespace",
-		"POOL_GROUP":                                      "pool-group",
-		// durations & bools work too; flag.Set expects the *string* form
-		"REFRESH_METRICS_INTERVAL":  "refresh-metrics-interval",
-		"SECURE_SERVING":            "secure-serving",
-		"HA_ENABLE_LEADER_ELECTION": "ha-enable-leader-election",
-	} {
-		if v := os.Getenv(env); v != "" {
-			// ignore error; Parse() will catch invalid values later
-			_ = flag.Set(flg, v)
-		}
-	}
-}
-
 func (r *Runner) Run(ctx context.Context) error {
-	// Defaults already baked into flag declarations
-	// Load env vars as "soft" overrides
-	bindEnvToFlags()
-
 	opts := zap.Options{
 		Development: true,
 	}
@@ -245,40 +167,12 @@ func (r *Runner) Run(ctx context.Context) error {
 	}
 
 	// --- Setup Datastore ---
-	mapping, err := backendmetrics.NewMetricMapping(
-		*totalQueuedRequestsMetric,
-		*kvCacheUsagePercentageMetric,
-		*loraInfoMetric,
-	)
+	useDatalayerV2 := env.GetEnvBool(enableExperimentalDatalayerV2, false, setupLog)
+	epf, err := r.setupMetricsCollection(setupLog, useDatalayerV2)
 	if err != nil {
-		setupLog.Error(err, "Failed to create metric mapping from flags.")
 		return err
 	}
-	verifyMetricMapping(*mapping, setupLog)
-
-	var metricsHttpClient *http.Client
-	if *modelServerMetricsScheme == "https" {
-		metricsHttpClient = &http.Client{
-			Transport: &http.Transport{
-				TLSClientConfig: &tls.Config{
-					InsecureSkipVerify: *modelServerMetricsHttpsInsecureSkipVerify,
-				},
-			},
-		}
-	} else {
-		metricsHttpClient = http.DefaultClient
-	}
-
-	pmf := backendmetrics.NewPodMetricsFactory(&backendmetrics.PodMetricsClientImpl{
-		MetricMapping:            mapping,
-		ModelServerMetricsPort:   int32(*modelServerMetricsPort),
-		ModelServerMetricsPath:   *modelServerMetricsPath,
-		ModelServerMetricsScheme: *modelServerMetricsScheme,
-		Client:                   metricsHttpClient,
-	},
-		*refreshMetricsInterval)
-
-	datastore := datastore.NewDatastore(ctx, pmf)
+	datastore := datastore.NewDatastore(ctx, epf)
 
 	// --- Setup Metrics Server ---
 	customCollectors := []prometheus.Collector{collectors.NewInferencePoolMetricsCollector(datastore)}
@@ -294,9 +188,20 @@ func (r *Runner) Run(ctx context.Context) error {
 		FilterProvider: filters.WithAuthenticationAndAuthorization,
 	}
 
+	// Determine pool namespace: if --pool-namespace is non-empty, use it; else NAMESPACE env var; else default
+	resolvePoolNamespace := func() string {
+		if *poolNamespace != "" {
+			return *poolNamespace
+		}
+		if nsEnv := os.Getenv("NAMESPACE"); nsEnv != "" {
+			return nsEnv
+		}
+		return runserver.DefaultPoolNamespace
+	}
+	resolvedPoolNamespace := resolvePoolNamespace()
 	poolNamespacedName := types.NamespacedName{
 		Name:      *poolName,
-		Namespace: *poolNamespace,
+		Namespace: resolvedPoolNamespace,
 	}
 	poolGroupKind := schema.GroupKind{
 		Group: *poolGroup,
@@ -335,6 +240,8 @@ func (r *Runner) Run(ctx context.Context) error {
 			setupLog.Error(err, "Failed to setup pprof handlers")
 			return err
 		}
+		runtime.SetMutexProfileFraction(1)
+		runtime.SetBlockProfileRate(1)
 	}
 
 	err = r.parsePluginsConfiguration(ctx)
@@ -354,7 +261,7 @@ func (r *Runner) Run(ctx context.Context) error {
 
 	scheduler := scheduling.NewSchedulerWithConfig(r.schedulerConfig)
 
-	saturationDetector := saturationdetector.NewDetector(sdConfig, datastore, setupLog)
+	saturationDetector := saturationdetector.NewDetector(sdConfig, setupLog)
 
 	director := requestcontrol.NewDirectorWithConfig(datastore, scheduler, saturationDetector, r.requestControlConfig)
 
@@ -371,6 +278,7 @@ func (r *Runner) Run(ctx context.Context) error {
 		MetricsStalenessThreshold:        *metricsStalenessThreshold,
 		Director:                         director,
 		SaturationDetector:               saturationDetector,
+		UseExperimentalDatalayerV2:       useDatalayerV2, // pluggable data layer feature flag
 	}
 	if err := serverRunner.SetupWithManager(ctx, mgr); err != nil {
 		setupLog.Error(err, "Failed to setup EPP controllers")
@@ -404,6 +312,7 @@ func (r *Runner) registerInTreePlugins() {
 	plugins.Register(prefix.PrefixCachePluginType, prefix.PrefixCachePluginFactory)
 	plugins.Register(picker.MaxScorePickerType, picker.MaxScorePickerFactory)
 	plugins.Register(picker.RandomPickerType, picker.RandomPickerFactory)
+	plugins.Register(picker.WeightedRandomPickerType, picker.WeightedRandomPickerFactory)
 	plugins.Register(profile.SingleProfileHandlerType, profile.SingleProfileHandlerFactory)
 	plugins.Register(scorer.KvCacheUtilizationScorerType, scorer.KvCacheUtilizationScorerFactory)
 	plugins.Register(scorer.QueueScorerType, scorer.QueueScorerFactory)
@@ -446,6 +355,81 @@ func (r *Runner) parsePluginsConfiguration(ctx context.Context) error {
 	return nil
 }
 
+func (r *Runner) setupMetricsCollection(setupLog logr.Logger, useExperimentalDatalayer bool) (datalayer.EndpointFactory, error) {
+	if useExperimentalDatalayer {
+		return setupDatalayer()
+	}
+
+	if len(datalayer.GetSources()) != 0 {
+		setupLog.Info("data sources registered but pluggable datalayer is disabled")
+	}
+	return setupMetricsV1(setupLog)
+}
+
+func setupMetricsV1(setupLog logr.Logger) (datalayer.EndpointFactory, error) {
+	mapping, err := backendmetrics.NewMetricMapping(
+		*totalQueuedRequestsMetric,
+		*kvCacheUsagePercentageMetric,
+		*loraInfoMetric,
+	)
+	if err != nil {
+		setupLog.Error(err, "Failed to create metric mapping from flags.")
+		return nil, err
+	}
+	verifyMetricMapping(*mapping, setupLog)
+
+	var metricsHttpClient *http.Client
+	if *modelServerMetricsScheme == "https" {
+		metricsHttpClient = &http.Client{
+			Transport: &http.Transport{
+				TLSClientConfig: &tls.Config{
+					InsecureSkipVerify: *modelServerMetricsHttpsInsecureSkipVerify,
+				},
+			},
+		}
+	} else {
+		metricsHttpClient = http.DefaultClient
+	}
+
+	pmf := backendmetrics.NewPodMetricsFactory(&backendmetrics.PodMetricsClientImpl{
+		MetricMapping:            mapping,
+		ModelServerMetricsPort:   int32(*modelServerMetricsPort),
+		ModelServerMetricsPath:   *modelServerMetricsPath,
+		ModelServerMetricsScheme: *modelServerMetricsScheme,
+		Client:                   metricsHttpClient,
+	},
+		*refreshMetricsInterval)
+	return pmf, nil
+}
+
+func setupDatalayer() (datalayer.EndpointFactory, error) {
+	// create and register a metrics data source and extractor. In the future,
+	// data sources and extractors might be configured via a file. Once done,
+	// this (and registering the sources with the endpoint factory) should
+	// be moved accordingly.
+	source := dlmetrics.NewDataSource(*modelServerMetricsScheme,
+		int32(*modelServerMetricsPort), // start with (optional) command line port value
+		*modelServerMetricsPath,
+		*modelServerMetricsHttpsInsecureSkipVerify,
+		nil)
+	extractor, err := dlmetrics.NewExtractor(*totalQueuedRequestsMetric,
+		*kvCacheUsagePercentageMetric,
+		*loraInfoMetric)
+
+	if err != nil {
+		return nil, err
+	}
+	if err := source.AddExtractor(extractor); err != nil {
+		return nil, err
+	}
+	if err := datalayer.RegisterSource(source); err != nil {
+		return nil, err
+	}
+
+	factory := datalayer.NewEndpointFactory(datalayer.GetSources(), *refreshMetricsInterval)
+	return factory, nil
+}
+
 func initLogging(opts *zap.Options) {
 	// Unless -zap-log-level is explicitly set, use -v
 	useV := true
diff --git a/config/charts/inferencepool/README.md b/config/charts/inferencepool/README.md
index edc01d2..41fee83 100644
--- a/config/charts/inferencepool/README.md
+++ b/config/charts/inferencepool/README.md
@@ -16,7 +16,7 @@ To install via the latest published chart in staging  (--version v0 indicates la
 ```txt
 $ helm install vllm-llama3-8b-instruct \
   --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
-  --set provider.name=[none|gke] \
+  --set provider.name=[none|gke|istio] \
   oci://us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/charts/inferencepool --version v0
 ```
 
@@ -45,6 +45,26 @@ Then apply it with:
 $ helm install vllm-llama3-8b-instruct ./config/charts/inferencepool -f values.yaml
 ```
 
+### Install with Custom EPP Plugins Configuration
+
+To set custom EPP plugin config, you can pass it as an inline yaml. For example:
+
+```yaml
+  inferenceExtension:
+    pluginsCustomConfig:
+      custom-plugins.yaml: |
+        apiVersion: inference.networking.x-k8s.io/v1alpha1
+        kind: EndpointPickerConfig
+        plugins:
+        - type: custom-scorer
+          parameters:
+            custom-threshold: 64
+        schedulingProfiles:
+        - name: default
+          plugins:
+          - pluginRef: custom-scorer
+```
+
 ### Install with Additional Ports
 
 To expose additional ports (e.g., for ZMQ), you can define them in the `values.yaml` file:
@@ -75,26 +95,63 @@ Use `--set inferencePool.modelServerType=triton-tensorrt-llm` to install for Tri
 $ helm install triton-llama3-8b-instruct \
   --set inferencePool.modelServers.matchLabels.app=triton-llama3-8b-instruct \
   --set inferencePool.modelServerType=triton-tensorrt-llm \
-  --set provider.name=[none|gke] \
+  --set provider.name=[none|gke|istio] \
   oci://us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/charts/inferencepool --version v0
 ```
 
 ### Install with High Availability (HA)
 
-To deploy the EndpointPicker in a high-availability (HA) active-passive configuration, you can enable leader election. When enabled, the EPP deployment will have multiple replicas, but only one "leader" replica will be active and ready to process traffic at any given time. If the leader pod fails, another pod will be elected as the new leader, ensuring service continuity.
+To deploy the EndpointPicker in a high-availability (HA) active-passive configuration set replicas to be greater than one. In such a setup, only one "leader" replica will be active and ready to process traffic at any given time. If the leader pod fails, another pod will be elected as the new leader, ensuring service continuity.
+
+To enable HA, set `inferenceExtension.replicas` to a number greater than 1.
+
+* Via `--set` flag:
+
+  ```txt
+  helm install vllm-llama3-8b-instruct \
+  --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
+  --set inferenceExtension.replicas=3 \
+  --set provider=[none|gke] \
+  oci://us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/charts/inferencepool --version v0
+  ```
+
+* Via `values.yaml`:
+
+  ```yaml
+  inferenceExtension:
+    replicas: 3
+  ```
+
+  Then apply it with:
+
+  ```txt
+  helm install vllm-llama3-8b-instruct ./config/charts/inferencepool -f values.yaml
+  ```
+
+### Install with Monitoring
 
-To enable HA, set `inferenceExtension.enableLeaderElection` to `true` and increase the number of replicas in your `values.yaml` file:
+To enable metrics collection and monitoring for the EndpointPicker, you can configure Prometheus ServiceMonitor creation:
 
 ```yaml
 inferenceExtension:
-  replicas: 3
-  enableLeaderElection: true
+  monitoring:
+    interval: "10s"
+    prometheus:
+      enabled: true
+    secret:
+      name: inference-gateway-sa-metrics-reader-secret
 ```
 
+**Note:** Prometheus monitoring requires the Prometheus Operator and ServiceMonitor CRD to be installed in the cluster.
+
+For GKE environments, monitoring is enabled by setting `provider.name` to `gke` and `inferenceExtension.monitoring.gke.enabled` to `true`. This will create the necessary `PodMonitoring` and RBAC resources for metrics collection.
+
+If you are using a GKE Autopilot cluster, you also need to set `provider.gke.autopilot` to `true`.
+
 Then apply it with:
 
 ```txt
-helm install vllm-llama3-8b-instruct ./config/charts/inferencepool -f values.yaml \
+helm install vllm-llama3-8b-instruct ./config/charts/inferencepool -f values.yaml
 ```
 
 ## Uninstall
@@ -111,22 +168,51 @@ The following table list the configurable parameters of the chart.
 
 | **Parameter Name**                          | **Description**                                                                                                        |
 |---------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
+| `inferencePool.apiVersion`                  | The API version of the InferencePool resource. Defaults to `inference.networking.k8s.io/v1`. This can be changed to `inference.networking.x-k8s.io/v1alpha2` to support older API versions. |
 | `inferencePool.targetPortNumber`            | Target port number for the vllm backends, will be used to scrape metrics by the inference extension. Defaults to 8000. |
 | `inferencePool.modelServerType`            | Type of the model servers in the pool, valid options are [vllm, triton-tensorrt-llm], default is vllm. |
 | `inferencePool.modelServers.matchLabels`    | Label selector to match vllm backends managed by the inference pool.                                                   |
-| `inferenceExtension.replicas`               | Number of replicas for the endpoint picker extension service. Defaults to `1`.                                         |
+| `inferenceExtension.replicas`               | Number of replicas for the endpoint picker extension service. If More than one replica is used, EPP will run in HA active-passive mode. Defaults to `1`.                                         |
 | `inferenceExtension.image.name`             | Name of the container image used for the endpoint picker.                                                              |
 | `inferenceExtension.image.hub`              | Registry URL where the endpoint picker image is hosted.                                                                |
 | `inferenceExtension.image.tag`              | Image tag of the endpoint picker.                                                                                      |
 | `inferenceExtension.image.pullPolicy`       | Image pull policy for the container. Possible values: `Always`, `IfNotPresent`, or `Never`. Defaults to `Always`.      |
-| `inferenceExtension.extProcPort`            | Port where the endpoint picker service is served for external processing. Defaults to `9002`.                          |
 | `inferenceExtension.env`                    | List of environment variables to set in the endpoint picker container as free-form YAML. Defaults to `[]`.             |
-| `inferenceExtension.extraContainerPorts`    | List of additional container ports to expose. Defaults to `[]`.                                                       |
-| `inferenceExtension.extraServicePorts`      | List of additional service ports to expose. Defaults to `[]`.                                                         |
-| `inferenceExtension.logVerbosity`           | Logging verbosity level for the endpoint picker. Defaults to `"3"`.                                                   |
-| `provider.name`                             | Name of the Inference Gateway implementation being used. Possible values: `gke`. Defaults to `none`.                   |
-| `inferenceExtension.enableLeaderElection`   | Enable leader election for high availability. When enabled, only one EPP pod (the leader) will be ready to serve traffic. It is recommended to set `inferenceExtension.replicas` to a value greater than 1 when this is set to `true`. Defaults to `false`. |
+| `inferenceExtension.extraContainerPorts`    | List of additional container ports to expose. Defaults to `[]`.                                                        |
+| `inferenceExtension.extraServicePorts`      | List of additional service ports to expose. Defaults to `[]`.                                                          |
+| `inferenceExtension.flags`                  | List of flags which are passed through to endpoint picker. Example flags, enable-pprof, grpc-port etc. Refer [runner.go](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/cmd/epp/runner/runner.go) for complete list.                                                            |
+| `inferenceExtension.affinity`               | Affinity for the endpoint picker. Defaults to `{}`.                                                                    |
+| `inferenceExtension.tolerations`            | Tolerations for the endpoint picker. Defaults to `[]`.                                                                 |   |
+| `inferenceExtension.monitoring.interval`   | Metrics scraping interval for monitoring. Defaults to `10s`.                                                           |
+| `inferenceExtension.monitoring.secret.name` | Name of the service account token secret for metrics authentication. Defaults to `inference-gateway-sa-metrics-reader-secret`. |
+| `inferenceExtension.monitoring.prometheus.enabled` | Enable Prometheus ServiceMonitor creation for EPP metrics collection. Defaults to `false`.                      |
+| `inferenceExtension.monitoring.gke.enabled` | Enable GKE monitoring resources (`PodMonitoring` and RBAC). Defaults to `false`. |
+| `inferenceExtension.pluginsCustomConfig`    | Custom config that is passed to EPP as inline yaml.      |
+| `provider.name`                             | Name of the Inference Gateway implementation being used. Possible values: [`none`, `gke`, or `istio`]. Defaults to `none`.                   |
+| `provider.gke.autopilot` | Set to `true` if the cluster is a GKE Autopilot cluster. This is only used if `provider.name` is `gke`. Defaults to `false`. |
+
+### Provider Specific Configuration
 
+This section should document any Gateway provider specific values configurations.
+
+#### GKE
+
+These are the options available to you with `provider.name` set to `gke`:
+
+| **Parameter Name**                          | **Description**                                                                                                        |
+|---------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
+| `gke.monitoringSecret.name`                 | The name of the monitoring secret to be used. Defaults to `inference-gateway-sa-metrics-reader-secret`.                |
+| `gke.monitoringSecret.namespace`            | The namespace that the monitoring secret lives in. Defaults to `default`.                                              |
+
+
+#### Istio
+
+These are the options available to you with `provider.name` set to `istio`:
+
+| **Parameter Name**                          | **Description**                                                                                                        |
+|---------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
+| `istio.destinationRule.host`            | Custom host value for the destination rule. If not set this will use the default value which is derrived from the epp service name and release namespace to gerenate a valid service address. |
+| `istio.destinationRule.trafficPolicy.connectionPool`            | Configure the connectionPool level settings of the traffic policy |
 
 ## Notes
 
diff --git a/config/charts/inferencepool/templates/_helpers.tpl b/config/charts/inferencepool/templates/_helpers.tpl
index e011bb7..fdc9b1a 100644
--- a/config/charts/inferencepool/templates/_helpers.tpl
+++ b/config/charts/inferencepool/templates/_helpers.tpl
@@ -16,6 +16,15 @@ Inference extension name
 {{ $base }}-epp
 {{- end -}}
 
+{{/*
+Cluster RBAC unique name
+*/}}
+{{- define "gateway-api-inference-extension.cluster-rbac-name" -}}
+{{- $base := .Release.Name | default "default-pool" | lower | trim | trunc 40 }}
+{{- $ns := .Release.Namespace | default "default" | lower | trim | trunc 40 }}
+{{- printf "%s-%s-epp" $base $ns | quote | trunc 84 }}
+{{- end -}}
+
 {{/*
 Selector labels
 */}}
diff --git a/config/charts/inferencepool/templates/epp-deployment.yaml b/config/charts/inferencepool/templates/epp-deployment.yaml
index fc15449..f012c2e 100644
--- a/config/charts/inferencepool/templates/epp-deployment.yaml
+++ b/config/charts/inferencepool/templates/epp-deployment.yaml
@@ -7,6 +7,14 @@ metadata:
     {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
 spec:
   replicas: {{ .Values.inferenceExtension.replicas | default 1 }}
+  strategy:
+    # The current recommended EPP deployment pattern is to have a single active replica. This ensures 
+    # optimal performance of the stateful operations such prefix cache aware scorer.
+    # The Recreate strategy the old replica is killed immediately, and allow the new replica(s) to 
+    # quickly take over. This is particularly important in the high availability set up with leader
+    # election, as the rolling update strategy would prevent the old leader being killed because 
+    # otherwise the maxUnavailable would be 100%.
+    type: Recreate
   selector:
     matchLabels:
       {{- include "gateway-api-inference-extension.selectorLabels" . | nindent 6 }}
@@ -25,28 +33,19 @@ spec:
         args:
         - --pool-name
         - {{ .Release.Name }}
+        # The pool namespace is optional because EPP can default to the NAMESPACE env var.
+        # We still keep this here so that the template works with older versions of EPP, or other
+        # distros of EPP which may not have implemented the NAMESPACE env var defaulting behavior.
         - --pool-namespace
         - {{ .Release.Namespace }}
-        - --v
-        - "{{ .Values.inferenceExtension.logVerbosity | default "3" }}"
-        - --grpc-port
-        - "9002"
-        - --grpc-health-port
-        - "9003"
+        {{- if ne .Values.inferencePool.apiVersion "inference.networking.k8s.io" }}
+        - --pool-group
+        - "{{ (split "/" .Values.inferencePool.apiVersion)._0 }}"
+        {{- end }}
         - --zap-encoder
         - "json"
-        - --metrics-port
-        - "9090"
         - --config-file
-        - "config/{{ .Values.inferenceExtension.pluginsConfigFile }}"
-        # https://pkg.go.dev/flag#hdr-Command_line_flag_syntax; space is only for non-bool flags
-        - "--enable-pprof={{ .Values.inferenceExtension.enablePprof }}"
-        - "--model-server-metrics-path={{ .Values.inferenceExtension.modelServerMetricsPath }}"
-        - "--model-server-metrics-scheme={{ .Values.inferenceExtension.modelServerMetricsScheme }}"
-        - "--model-server-metrics-https-insecure-skip-verify={{ .Values.inferenceExtension.modelServerMetricsHttpsInsecureSkipVerify }}"
-        {{- if .Values.inferenceExtension.enableLeaderElection }}
-        - "--ha-enable-leader-election"
-        {{- end }}
+        - "/config/{{ .Values.inferenceExtension.pluginsConfigFile }}"
         {{- if eq (.Values.inferencePool.modelServerType | default "vllm") "triton-tensorrt-llm" }}
         - --total-queued-requests-metric
         - "nv_trt_llm_request_metrics{request_type=waiting}"
@@ -55,6 +54,14 @@ spec:
         - --lora-info-metric
         - "" # Set an empty metric to disable LoRA metric scraping as they are not supported by Triton yet.
         {{- end }}
+        {{- if gt (.Values.inferenceExtension.replicas | int) 1 }}
+        - --ha-enable-leader-election
+        {{- end }}
+        # Pass additional flags via the inferenceExtension.flags field in values.yaml.
+        {{- range .Values.inferenceExtension.flags }}
+        - "--{{ .name }}"
+        - "{{ .value }}"
+        {{- end }}
         ports:
         - name: grpc
           containerPort: 9002
@@ -62,11 +69,11 @@ spec:
           containerPort: 9003
         - name: metrics
           containerPort: 9090
-        {{- with .Values.inferenceExtension.extraContainerPorts }}
-        {{- toYaml . | nindent 8 }}
+        {{- if .Values.inferenceExtension.extraContainerPorts }}
+        {{- toYaml .Values.inferenceExtension.extraContainerPorts | nindent 8 }}
         {{- end }}
         livenessProbe:
-          {{- if .Values.inferenceExtension.enableLeaderElection }}
+          {{- if gt (.Values.inferenceExtension.replicas | int) 1 }}
           grpc:
             port: 9003
             service: liveness
@@ -78,7 +85,7 @@ spec:
           initialDelaySeconds: 5
           periodSeconds: 10
         readinessProbe:
-          {{- if .Values.inferenceExtension.enableLeaderElection }}
+          {{- if gt (.Values.inferenceExtension.replicas | int) 1 }}
           grpc:
             port: 9003
             service: readiness
@@ -87,11 +94,15 @@ spec:
             port: 9003
             service: inference-extension
           {{- end }}
-          initialDelaySeconds: 5
-          periodSeconds: 10
-        {{- with .Values.inferenceExtension.env }}
+          periodSeconds: 2
+
         env:
-        {{- toYaml . | nindent 8 }}
+        - name: NAMESPACE
+          valueFrom:
+            fieldRef:
+              fieldPath: metadata.namespace
+        {{- if .Values.inferenceExtension.env }}
+        {{- toYaml .Values.inferenceExtension.env | nindent 8 }}
         {{- end }}
         volumeMounts:
         - name: plugins-config-volume
@@ -100,3 +111,11 @@ spec:
       - name: plugins-config-volume
         configMap:
           name: {{ include "gateway-api-inference-extension.name" . }}
+      {{- if .Values.inferenceExtension.affinity }}
+      affinity:
+        {{- toYaml .Values.inferenceExtension.affinity | nindent 8 }}
+      {{- end }}
+      {{- if .Values.inferenceExtension.tolerations }}
+      tolerations:
+        {{- toYaml .Values.inferenceExtension.tolerations | nindent 8 }}
+      {{- end }}
diff --git a/config/charts/inferencepool/templates/epp-sa-token-secret.yaml b/config/charts/inferencepool/templates/epp-sa-token-secret.yaml
new file mode 100644
index 0000000..df54b34
--- /dev/null
+++ b/config/charts/inferencepool/templates/epp-sa-token-secret.yaml
@@ -0,0 +1,12 @@
+{{- if .Values.inferenceExtension.monitoring.prometheus.enabled }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ .Values.inferenceExtension.monitoring.secret.name }}
+  namespace: {{ .Release.Namespace }}
+  labels:
+    {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
+  annotations:
+    kubernetes.io/service-account.name: {{ include "gateway-api-inference-extension.name" . }}
+type: kubernetes.io/service-account-token
+{{- end }}
\ No newline at end of file
diff --git a/config/charts/inferencepool/templates/epp-servicemonitor.yaml b/config/charts/inferencepool/templates/epp-servicemonitor.yaml
new file mode 100644
index 0000000..e4788ba
--- /dev/null
+++ b/config/charts/inferencepool/templates/epp-servicemonitor.yaml
@@ -0,0 +1,25 @@
+{{- if .Values.inferenceExtension.monitoring.prometheus.enabled }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+  name: {{ include "gateway-api-inference-extension.name" . }}-monitor
+  namespace: {{ .Release.Namespace }}
+  labels:
+    {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
+spec:
+  endpoints:
+  - interval: {{ .Values.inferenceExtension.monitoring.interval }}
+    port: "http-metrics"
+    path: "/metrics"
+    authorization:
+      credentials:
+        key: token
+        name: {{ .Values.inferenceExtension.monitoring.secret.name }}
+  jobLabel: {{ include "gateway-api-inference-extension.name" . }}
+  namespaceSelector:
+    matchNames:
+    - {{ .Release.Namespace }}
+  selector:
+    matchLabels:
+      {{- include "gateway-api-inference-extension.labels" . | nindent 6 }}
+{{- end }}
diff --git a/config/charts/inferencepool/templates/gke.yaml b/config/charts/inferencepool/templates/gke.yaml
index 382549f..77855c3 100644
--- a/config/charts/inferencepool/templates/gke.yaml
+++ b/config/charts/inferencepool/templates/gke.yaml
@@ -1,4 +1,4 @@
-{{- if eq .Values.provider.name "gke" }}
+{{- if eq (lower .Values.provider.name) "gke" }}
 ---
 kind: HealthCheckPolicy
 apiVersion: networking.gke.io/v1
@@ -9,10 +9,14 @@ metadata:
     {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
 spec:
   targetRef:
-    group: "inference.networking.k8s.io"
+    group: "{{ (split "/" .Values.inferencePool.apiVersion)._0 }}"
     kind: InferencePool
     name: {{ .Release.Name }}
   default:
+    # Set a more aggressive health check than the default 5s for faster switch
+    # over during EPP rollout.
+    timeoutSec: 2
+    checkIntervalSec: 2
     config:
       type: HTTP
       httpHealthCheck:
@@ -28,7 +32,7 @@ metadata:
     {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
 spec:
   targetRef:
-    group: "inference.networking.k8s.io"
+    group: "{{ (split "/" .Values.inferencePool.apiVersion)._0 }}"
     kind: InferencePool
     name: {{ .Release.Name }}
   default:
@@ -36,26 +40,107 @@ spec:
     logging:
       enabled: true    # log all requests by default
 ---
+{{- if .Values.inferenceExtension.monitoring.gke.enabled }}
+{{- $metricsReadSA := printf "%s-metrics-reader-sa" .Release.Name -}}
+{{- $metricsReadSecretName := printf "%s-metrics-reader-secret" .Release.Name -}}
+{{- $metricsReadRoleName := printf "%s-%s-metrics-reader" .Release.Namespace .Release.Name -}}
+{{- $metricsReadRoleBindingName := printf "%s-%s-metrics-reader-role-binding" .Release.Namespace .Release.Name -}}
+{{- $secretReadRoleName := printf "%s-metrics-reader-secret-read" .Release.Name -}}
+{{- $gmpNamespace := "gmp-system" -}}
+{{- $isAutopilot := false -}}
+{{- with .Values.provider.gke }}
+  {{- $isAutopilot = .autopilot | default false -}}
+{{- end }}
+{{- if $isAutopilot -}}
+{{-   $gmpNamespace = "gke-gmp-system" -}}
+{{- end -}}
+{{- $gmpCollectorRoleBindingName := printf "%s:collector:%s-%s-metrics-reader-secret-read" $gmpNamespace .Release.Namespace .Release.Name -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ $metricsReadSA }}
+  namespace: {{ .Release.Namespace }}
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ $metricsReadSecretName }}
+  namespace: {{ .Release.Namespace }}
+  labels:
+    {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
+  annotations:
+    kubernetes.io/service-account.name: {{ $metricsReadSA }}
+type: kubernetes.io/service-account-token
+---
 apiVersion: monitoring.googleapis.com/v1
-kind: ClusterPodMonitoring
+kind: PodMonitoring
 metadata:
-  name: {{ .Release.Namespace }}-{{ .Release.Name }}
+  name: {{ .Release.Name }}
+  namespace: {{ .Release.Namespace }}
   labels:
     {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
 spec:
   endpoints:
   - port: metrics
     scheme: http
-    interval: 5s
+    interval: {{ .Values.inferenceExtension.monitoring.interval }}
     path: /metrics
     authorization:
       type: Bearer
       credentials:
         secret:
-          name: {{ .Values.gke.monitoringSecret.name }}
+          name: {{ $metricsReadSecretName }}
           key: token
-          namespace: {{ .Values.gke.monitoringSecret.namespace }}
   selector:
     matchLabels:
       {{- include "gateway-api-inference-extension.selectorLabels" . | nindent 8 }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: {{ $metricsReadRoleName }}
+rules:
+- nonResourceURLs:
+  - /metrics
+  verbs:
+  - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: {{ $metricsReadRoleBindingName }}
+subjects:
+- kind: ServiceAccount
+  name: {{ $metricsReadSA }}
+  namespace: {{ .Release.Namespace }}
+roleRef:
+  kind: ClusterRole
+  name: {{ $metricsReadRoleName }}
+  apiGroup: rbac.authorization.k8s.io
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: {{ $secretReadRoleName }}
+rules:
+- resources:
+  - secrets
+  apiGroups: [""]
+  verbs: ["get", "list", "watch"]
+  resourceNames: [{{ $metricsReadSecretName | quote }}]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: {{ $gmpCollectorRoleBindingName }}
+  namespace: {{ .Release.Namespace }}
+roleRef:
+  name: {{ $secretReadRoleName }}
+  kind: Role
+  apiGroup: rbac.authorization.k8s.io
+subjects:
+- name: collector
+  namespace: {{ $gmpNamespace }}
+  kind: ServiceAccount
+{{- end }}
 {{- end }}
diff --git a/config/charts/inferencepool/templates/inferencepool.yaml b/config/charts/inferencepool/templates/inferencepool.yaml
index ad13f2d..5c973b9 100644
--- a/config/charts/inferencepool/templates/inferencepool.yaml
+++ b/config/charts/inferencepool/templates/inferencepool.yaml
@@ -1,5 +1,26 @@
+{{ if eq .Values.inferencePool.apiVersion "inference.networking.x-k8s.io/v1alpha2"}}
+apiVersion: {{ .Values.inferencePool.apiVersion }}
+kind: InferencePool
+metadata:
+  name: {{ .Release.Name }}
+  namespace: {{ .Release.Namespace }}
+  labels:
+    {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
+spec:
+  targetPortNumber: {{ .Values.inferencePool.targetPortNumber | default 8000 }}
+  selector:
+    {{- if .Values.inferencePool.modelServers.matchLabels }}
+    {{- range $key, $value := .Values.inferencePool.modelServers.matchLabels }}
+    {{ $key }}: {{ quote $value }}
+    {{- end }}
+    {{- end }}
+  extensionRef:
+    name: {{ include "gateway-api-inference-extension.name" . }}
+    portNumber: {{ .Values.inferenceExtension.extProcPort | default 9002 }}
+    failureMode: {{ .Values.inferenceExtension.failureMode | default "FailClose" }}
+{{ else }}
 {{ include "gateway-api-inference-extension.validations.inferencepool.common" $ }}
-apiVersion: inference.networking.k8s.io/v1
+apiVersion: "inference.networking.k8s.io/v1"
 kind: InferencePool
 metadata:
   name: {{ .Release.Name }}
@@ -18,5 +39,10 @@ spec:
       {{ $key }}: {{ quote $value }}
       {{- end }}
       {{- end }}
-  extensionRef:
+  endpointPickerRef:
     name: {{ include "gateway-api-inference-extension.name" . }}
+    port:
+      number: {{ .Values.inferenceExtension.extProcPort | default 9002 }}
+{{- end }}
+
+
diff --git a/config/charts/inferencepool/templates/istio.yaml b/config/charts/inferencepool/templates/istio.yaml
new file mode 100644
index 0000000..b50c0b0
--- /dev/null
+++ b/config/charts/inferencepool/templates/istio.yaml
@@ -0,0 +1,16 @@
+{{- if eq .Values.provider.name "istio" }}
+apiVersion: networking.istio.io/v1beta1
+kind: DestinationRule
+metadata:
+  name: {{ include "gateway-api-inference-extension.name" . }}
+spec:
+  host: {{ .Values.istio.destinationRule.host | default (printf "%s.%s.svc.cluster.local" (include "gateway-api-inference-extension.name" .) .Release.Namespace) }}
+  trafficPolicy:
+    tls:
+      mode: SIMPLE
+      insecureSkipVerify: true
+    {{- if .Values.istio.destinationRule.trafficPolicy.connectionPool }}
+    connectionPool: 
+      {{- .Values.istio.destinationRule.trafficPolicy.connectionPool | toYaml | nindent 6 }}
+    {{- end }}
+{{- end }}
diff --git a/config/charts/inferencepool/templates/leader-election-rbac.yaml b/config/charts/inferencepool/templates/leader-election-rbac.yaml
index 923bdd6..11b3dd5 100644
--- a/config/charts/inferencepool/templates/leader-election-rbac.yaml
+++ b/config/charts/inferencepool/templates/leader-election-rbac.yaml
@@ -1,4 +1,4 @@
-{{- if .Values.inferenceExtension.enableLeaderElection }}
+{{- if gt (.Values.inferenceExtension.replicas | int) 1 }}
 ---
 kind: Role
 apiVersion: rbac.authorization.k8s.io/v1
diff --git a/config/charts/inferencepool/templates/rbac.yaml b/config/charts/inferencepool/templates/rbac.yaml
index a8d891c..ebe68c3 100644
--- a/config/charts/inferencepool/templates/rbac.yaml
+++ b/config/charts/inferencepool/templates/rbac.yaml
@@ -1,7 +1,7 @@
 kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
-  name: {{ include "gateway-api-inference-extension.name" . }}
+  name: {{ include "gateway-api-inference-extension.cluster-rbac-name" . }}
   labels:
     {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
 rules:
@@ -17,11 +17,17 @@ rules:
   - subjectaccessreviews
   verbs:
   - create
+{{- if .Values.inferenceExtension.monitoring.prometheus.enabled }}
+- nonResourceURLs:
+  - "/metrics"
+  verbs:
+  - get
+{{- end }}
 ---
 kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
-  name: {{ include "gateway-api-inference-extension.name" . }}
+  name: {{ include "gateway-api-inference-extension.cluster-rbac-name" . }}
 subjects:
 - kind: ServiceAccount
   name: {{ include "gateway-api-inference-extension.name" . }}
@@ -29,7 +35,7 @@ subjects:
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
-  name: {{ include "gateway-api-inference-extension.name" . }}
+  name: {{ include "gateway-api-inference-extension.cluster-rbac-name" . }}
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
@@ -40,9 +46,9 @@ metadata:
     {{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
 rules:
 - apiGroups: ["inference.networking.x-k8s.io"]
-  resources: ["inferenceobjectives", "inferencepools"]
+  resources: ["inferenceobjectives"]
   verbs: ["get", "watch", "list"]
-- apiGroups: ["inference.networking.k8s.io"]
+- apiGroups: ["{{ (split "/" .Values.inferencePool.apiVersion)._0 }}"]
   resources: ["inferencepools"]
   verbs: ["get", "watch", "list"]
 - apiGroups: [""]
diff --git a/config/charts/inferencepool/values.yaml b/config/charts/inferencepool/values.yaml
index f89a63f..91d6a48 100644
--- a/config/charts/inferencepool/values.yaml
+++ b/config/charts/inferencepool/values.yaml
@@ -7,12 +7,13 @@ inferenceExtension:
     pullPolicy: Always
   extProcPort: 9002
   env: []
-  enablePprof: true # Enable pprof handlers for profiling and debugging
-  modelServerMetricsPath: "/metrics"
-  modelServerMetricsScheme: "http"
-  modelServerMetricsHttpsInsecureSkipVerify: true
-  # This is the plugins configuration file. 
   pluginsConfigFile: "default-plugins.yaml"
+  # Define additional container ports
+  extraContainerPorts: []
+  # Define additional service ports
+  extraServicePorts: []
+
+  # This is the plugins configuration file.
   # pluginsCustomConfig:
   #   custom-plugins.yaml: |
   #     apiVersion: inference.networking.x-k8s.io/v1alpha1
@@ -30,26 +31,58 @@ inferenceExtension:
   # env:
   #   ENABLE_EXPERIMENTAL_FEATURE: "true"
 
-  # Define additional container ports
-  extraContainerPorts: []
-  # Define additional service ports
-  extraServicePorts: []
-  # Enable leader election for high availability. When enabled, it is recommended to set replicas > 1.
-  # Only the leader pod will be ready to serve traffic.
-  enableLeaderElection: false
+  flags:
+    # Log verbosity
+    - name: v
+      value: 1
+
+  affinity: {}
+
+  tolerations: []
+
+  # Monitoring configuration for EPP
+  monitoring:
+    interval: "10s"
+    # Service account token secret for authentication
+    secret:
+      name: inference-gateway-sa-metrics-reader-secret
+
+    # Prometheus ServiceMonitor will be created when enabled for EPP metrics collection
+    prometheus:
+      enabled: false
+    
+    gke:
+      enabled: false
 
 inferencePool:
   targetPorts:
     - number: 8000
   modelServerType: vllm # vllm, triton-tensorrt-llm
-  modelServers: # REQUIRED
-    matchLabels:
-      app: vllm-llama3-8b-instruct
+  apiVersion: inference.networking.k8s.io/v1 
+  # modelServers: # REQUIRED
+  #   matchLabels:
+  #     app: vllm-llama3-8b-instruct
+
+  # Should only used if apiVersion is inference.networking.x-k8s.io/v1alpha2, 
+  # This will soon be deprecated when upstream GW providers support v1, just doing something simple for now.
+  targetPortNumber: 8000
 
+# Options: ["gke", "istio", "none"]
 provider:
   name: none
 
-gke:
-  monitoringSecret:
-    name: inference-gateway-sa-metrics-reader-secret
-    namespace: default
+  # GKE-specific configuration.
+  # This block is only used if name is "gke".
+  gke:
+    # Set to true if the cluster is an Autopilot cluster.
+    autopilot: false
+
+istio:
+  destinationRule:
+    # Provide a way to override the default calculated host
+    host: "" 
+    # Optional: Enables customization of the traffic policy
+    trafficPolicy: {}
+      # connectionPool:
+      #   http:
+      #     maxRequestsPerConnection: 256000
diff --git a/config/crd/bases/inference.networking.k8s.io_inferencepools.yaml b/config/crd/bases/inference.networking.k8s.io_inferencepools.yaml
index 92072eb..26ac568 100644
--- a/config/crd/bases/inference.networking.k8s.io_inferencepools.yaml
+++ b/config/crd/bases/inference.networking.k8s.io_inferencepools.yaml
@@ -2,9 +2,8 @@ apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    api-approved.kubernetes.io: unapproved, experimental-only
+    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api-inference-extension/pull/1173
     inference.networking.k8s.io/bundle-version: main-dev
-  creationTimestamp: null
   name: inferencepools.inference.networking.k8s.io
 spec:
   group: inference.networking.k8s.io
@@ -41,17 +40,18 @@ spec:
           metadata:
             type: object
           spec:
-            description: InferencePoolSpec defines the desired state of InferencePool
+            description: Spec defines the desired state of the InferencePool.
             properties:
-              extensionRef:
-                description: Extension configures an endpoint picker as an extension
-                  service.
+              endpointPickerRef:
+                description: |-
+                  EndpointPickerRef is a reference to the Endpoint Picker extension and its
+                  associated configuration.
                 properties:
                   failureMode:
                     default: FailClose
                     description: |-
-                      Configures how the gateway handles the case when the extension is not responsive.
-                      Defaults to failClose.
+                      FailureMode configures how the parent handles the case when the Endpoint Picker extension
+                      is non-responsive. When unspecified, defaults to "FailClose".
                     enum:
                     - FailOpen
                     - FailClose
@@ -59,8 +59,8 @@ spec:
                   group:
                     default: ""
                     description: |-
-                      Group is the group of the referent.
-                      The default value is "", representing the Core API group.
+                      Group is the group of the referent API object. When unspecified, the default value
+                      is "", representing the Core API group.
                     maxLength: 253
                     minLength: 0
                     pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -70,6 +70,8 @@ spec:
                     description: |-
                       Kind is the Kubernetes resource kind of the referent.
 
+                      Required if the referent is ambiguous, e.g. service with multiple ports.
+
                       Defaults to "Service" when not specified.
 
                       ExternalName services can refer to CNAME DNS records that may live
@@ -82,22 +84,37 @@ spec:
                     pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
                     type: string
                   name:
-                    description: Name is the name of the referent.
+                    description: Name is the name of the referent API object.
                     maxLength: 253
                     minLength: 1
                     type: string
-                  portNumber:
+                  port:
                     description: |-
-                      The port number on the service running the extension. When unspecified,
-                      implementations SHOULD infer a default value of 9002 when the Kind is
-                      Service.
-                    format: int32
-                    maximum: 65535
-                    minimum: 1
-                    type: integer
+                      Port is the port of the Endpoint Picker extension service.
+
+                      Port is required when the referent is a Kubernetes Service. In this
+                      case, the port number is the service port number, not the target port.
+                      For other resources, destination port might be derived from the referent
+                      resource or this field.
+                    properties:
+                      number:
+                        description: |-
+                          Number defines the port number to access the selected model server Pods.
+                          The number must be in the range 1 to 65535.
+                        format: int32
+                        maximum: 65535
+                        minimum: 1
+                        type: integer
+                    required:
+                    - number
+                    type: object
                 required:
                 - name
                 type: object
+                x-kubernetes-validations:
+                - message: port is required when kind is 'Service' or unspecified
+                    (defaults to 'Service')
+                  rule: self.kind != 'Service' || has(self.port)
               selector:
                 description: |-
                   Selector determines which Pods are members of this inference pool.
@@ -127,7 +144,7 @@ spec:
                       pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$
                       type: string
                     description: |-
-                      matchLabels contains a set of required {key,value} pairs.
+                      MatchLabels contains a set of required {key,value} pairs.
                       An object must match every label in this map to be selected.
                       The matching logic is an AND operation on all entries.
                     type: object
@@ -137,7 +154,8 @@ spec:
               targetPorts:
                 description: |-
                   TargetPorts defines a list of ports that are exposed by this InferencePool.
-                  Currently, the list may only include a single port definition.
+                  Every port will be treated as a distinctive endpoint by EPP,
+                  addressable as a 'podIP:portNumber' combination.
                 items:
                   description: Port defines the network port that will be exposed
                     by this InferencePool.
@@ -153,60 +171,43 @@ spec:
                   required:
                   - number
                   type: object
-                maxItems: 1
+                maxItems: 8
                 minItems: 1
                 type: array
-                x-kubernetes-list-map-keys:
-                - number
-                x-kubernetes-list-type: map
+                x-kubernetes-list-type: atomic
+                x-kubernetes-validations:
+                - message: port number must be unique
+                  rule: self.all(p1, self.exists_one(p2, p1.number==p2.number))
             required:
-            - extensionRef
+            - endpointPickerRef
             - selector
             - targetPorts
             type: object
           status:
-            default:
-              parent:
-              - conditions:
-                - lastTransitionTime: "1970-01-01T00:00:00Z"
-                  message: Waiting for controller
-                  reason: Pending
-                  status: Unknown
-                  type: Accepted
-                parentRef:
-                  kind: Status
-                  name: default
-            description: Status defines the observed state of InferencePool.
-            minProperties: 1
+            description: Status defines the observed state of the InferencePool.
             properties:
-              parent:
+              parents:
                 description: |-
-                  Parents is a list of parent resources (usually Gateways) that are
-                  associated with the InferencePool, and the status of the InferencePool with respect to
-                  each parent.
+                  Parents is a list of parent resources, typically Gateways, that are associated with
+                  the InferencePool, and the status of the InferencePool with respect to each parent.
 
-                  A maximum of 32 Gateways will be represented in this list. When the list contains
-                  `kind: Status, name: default`, it indicates that the InferencePool is not
-                  associated with any Gateway and a controller must perform the following:
+                  A controller that manages the InferencePool, must add an entry for each parent it manages
+                  and remove the parent entry when the controller no longer considers the InferencePool to
+                  be associated with that parent.
 
-                   - Remove the parent when setting the "Accepted" condition.
-                   - Add the parent when the controller will no longer manage the InferencePool
-                     and no other parents exist.
+                  A maximum of 32 parents will be represented in this list. When the list is empty,
+                  it indicates that the InferencePool is not associated with any parents.
                 items:
-                  description: PoolStatus defines the observed state of InferencePool
-                    from a Gateway.
+                  description: ParentStatus defines the observed state of InferencePool
+                    from a Parent, i.e. Gateway.
                   properties:
                     conditions:
-                      default:
-                      - lastTransitionTime: "1970-01-01T00:00:00Z"
-                        message: Waiting for controller
-                        reason: Pending
-                        status: Unknown
-                        type: Accepted
                       description: |-
-                        Conditions track the state of the InferencePool.
+                        Conditions is a list of status conditions that provide information about the observed
+                        state of the InferencePool. This field is required to be set by the controller that
+                        manages the InferencePool.
 
-                        Known condition types are:
+                        Supported condition types are:
 
                         * "Accepted"
                         * "ResolvedRefs"
@@ -270,34 +271,63 @@ spec:
                       x-kubernetes-list-map-keys:
                       - type
                       x-kubernetes-list-type: map
+                    controllerName:
+                      description: |-
+                        ControllerName is a domain/path string that indicates the name of the controller that
+                        wrote this status. This corresponds with the GatewayClass controllerName field when the
+                        parentRef references a Gateway kind.
+
+                        Example: "example.net/gateway-controller".
+
+                        The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are valid Kubernetes names:
+
+                         https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+
+                        Controllers MAY populate this field when writing status. When populating this field, controllers
+                        should ensure that entries to status populated with their ControllerName are cleaned up when they
+                        are no longer necessary.
+                      maxLength: 253
+                      minLength: 1
+                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
+                      type: string
                     parentRef:
-                      description: GatewayRef indicates the gateway that observed
-                        state of InferencePool.
+                      description: |-
+                        ParentRef is used to identify the parent resource that this status
+                        is associated with. It is used to match the InferencePool with the parent
+                        resource, such as a Gateway.
                       properties:
                         group:
                           default: gateway.networking.k8s.io
-                          description: Group is the group of the referent.
+                          description: |-
+                            Group is the group of the referent API object. When unspecified, the referent is assumed
+                            to be in the "gateway.networking.k8s.io" API group.
                           maxLength: 253
                           minLength: 0
                           pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                           type: string
                         kind:
                           default: Gateway
-                          description: Kind is kind of the referent. For example "Gateway".
+                          description: |-
+                            Kind is the kind of the referent API object. When unspecified, the referent is assumed
+                            to be a "Gateway" kind.
                           maxLength: 63
                           minLength: 1
                           pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
                           type: string
                         name:
-                          description: Name is the name of the referent.
+                          description: Name is the name of the referent API object.
                           maxLength: 253
                           minLength: 1
                           type: string
                         namespace:
                           description: |-
-                            Namespace is the namespace of the referent.  If not present,
-                            the namespace of the referent is assumed to be the same as
-                            the namespace of the referring object.
+                            Namespace is the namespace of the referenced object. When unspecified, the local
+                            namespace is inferred.
+
+                            Note that when a namespace different than the local namespace is specified,
+                            a ReferenceGrant object is required in the referent namespace to allow that
+                            namespace's owner to accept the reference. See the ReferenceGrant
+                            documentation for details: https://gateway-api.sigs.k8s.io/api-types/referencegrant/
                           maxLength: 63
                           minLength: 1
                           pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
diff --git a/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml b/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml
index 7f0968f..836aac4 100644
--- a/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml
+++ b/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml
@@ -3,7 +3,6 @@ kind: CustomResourceDefinition
 metadata:
   annotations:
     inference.networking.k8s.io/bundle-version: main-dev
-  creationTimestamp: null
   name: inferenceobjectives.inference.networking.x-k8s.io
 spec:
   group: inference.networking.x-k8s.io
@@ -15,9 +14,6 @@ spec:
   scope: Namespaced
   versions:
   - additionalPrinterColumns:
-    - jsonPath: .spec.modelName
-      name: Model Name
-      type: string
     - jsonPath: .spec.poolRef.name
       name: Inference Pool
       type: string
@@ -61,12 +57,6 @@ spec:
               performance and latency goals for the model. These workloads are
               expected to operate within an InferencePool sharing compute capacity with other
               InferenceObjectives, defined by the Inference Platform Admin.
-
-              InferenceObjective's modelName (not the ObjectMeta name) is unique for a given InferencePool,
-              if the name is reused, an error will be shown on the status of a
-              InferenceObjective that attempted to reuse. The oldest InferenceObjective, based on
-              creation timestamp, will be selected to remain valid. In the event of a race
-              condition, one will be selected at random.
             properties:
               poolRef:
                 description: PoolRef is a reference to the inference pool, the pool
@@ -100,7 +90,7 @@ spec:
                   The higher the value, the more critical the request is; negative values _are_ allowed.
                   No default value is set for this field, allowing for future additions of new fields that may 'one of' with this field.
                   However, implementations that consume this field (such as the Endpoint Picker) will treat an unset value as '0'.
-                  Priority is used in flow control, primarily in the event of resource scarcity(reqeusts need to be queued).
+                  Priority is used in flow control, primarily in the event of resource scarcity(requests need to be queued).
                   All requests will be queued, and flow control will _always_ allow requests of higher priority to be served first.
                   Fairness is only enforced and tracked between requests of the same priority.
 
diff --git a/config/crd/bases/inference.networking.x-k8s.io_inferencepoolimports.yaml b/config/crd/bases/inference.networking.x-k8s.io_inferencepoolimports.yaml
new file mode 100644
index 0000000..318e6d4
--- /dev/null
+++ b/config/crd/bases/inference.networking.x-k8s.io_inferencepoolimports.yaml
@@ -0,0 +1,330 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    inference.networking.k8s.io/bundle-version: main-dev
+  name: inferencepoolimports.inference.networking.x-k8s.io
+spec:
+  group: inference.networking.x-k8s.io
+  names:
+    kind: InferencePoolImport
+    listKind: InferencePoolImportList
+    plural: inferencepoolimports
+    shortNames:
+    - infpimp
+    singular: inferencepoolimport
+  scope: Namespaced
+  versions:
+  - name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        description: InferencePoolImport is the Schema for the InferencePoolImports
+          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
+          status:
+            description: Status defines the observed state of the InferencePoolImport.
+            properties:
+              controllers:
+                description: Controllers is a list of controllers that are responsible
+                  for managing the InferencePoolImport.
+                items:
+                  description: ImportController defines a controller that is responsible
+                    for managing the InferencePoolImport.
+                  properties:
+                    conditions:
+                      description: |-
+                        Conditions track the state of the InferencePoolImport.
+
+                        Known condition types are:
+
+                         * "Accepted"
+                      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
+                      maxItems: 8
+                      type: array
+                      x-kubernetes-list-map-keys:
+                      - type
+                      x-kubernetes-list-type: map
+                    exportingClusters:
+                      description: |-
+                        ExportingClusters is a list of clusters that exported the InferencePool(s) that back the
+                        InferencePoolImport. Required when the controller is responsible for CRUD'ing the InferencePoolImport
+                        from the exported InferencePool(s).
+                      items:
+                        description: ExportingCluster defines a cluster that exported
+                          the InferencePool that backs this InferencePoolImport.
+                        properties:
+                          name:
+                            description: Name of the exporting cluster (must be unique
+                              within the list).
+                            maxLength: 253
+                            minLength: 1
+                            type: string
+                        required:
+                        - name
+                        type: object
+                      type: array
+                    name:
+                      description: |-
+                        Name is a domain/path string that indicates the name of the controller that manages the
+                        InferencePoolImport. Name corresponds to the GatewayClass controllerName field when the
+                        controller will manage parents of type "Gateway". Otherwise, the name is implementation-specific.
+
+                        Example: "example.net/import-controller".
+
+                        The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are valid Kubernetes
+                        names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+
+                        A controller MUST populate this field when writing status and ensure that entries to status
+                        populated with their controller name are removed when they are no longer necessary.
+                      maxLength: 253
+                      minLength: 1
+                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
+                      type: string
+                    parents:
+                      description: |-
+                        Parents is a list of parent resources, typically Gateways, that are associated with the
+                        InferencePoolImport, and the status of the InferencePoolImport with respect to each parent.
+
+                        Ancestor would be a more accurate name, but Parent is consistent with InferencePool terminology.
+
+                        Required when the controller manages the InferencePoolImport as an HTTPRoute backendRef. The controller
+                        must add an entry for each parent it manages and remove the parent entry when the controller no longer
+                        considers the InferencePoolImport to be associated with that parent.
+                      items:
+                        description: ParentStatus defines the observed state of InferencePool
+                          from a Parent, i.e. Gateway.
+                        properties:
+                          conditions:
+                            description: |-
+                              Conditions is a list of status conditions that provide information about the observed
+                              state of the InferencePool. This field is required to be set by the controller that
+                              manages the InferencePool.
+
+                              Supported condition types are:
+
+                              * "Accepted"
+                              * "ResolvedRefs"
+                            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
+                            maxItems: 8
+                            type: array
+                            x-kubernetes-list-map-keys:
+                            - type
+                            x-kubernetes-list-type: map
+                          controllerName:
+                            description: |-
+                              ControllerName is a domain/path string that indicates the name of the controller that
+                              wrote this status. This corresponds with the GatewayClass controllerName field when the
+                              parentRef references a Gateway kind.
+
+                              Example: "example.net/gateway-controller".
+
+                              The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are valid Kubernetes names:
+
+                               https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+
+                              Controllers MAY populate this field when writing status. When populating this field, controllers
+                              should ensure that entries to status populated with their ControllerName are cleaned up when they
+                              are no longer necessary.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
+                            type: string
+                          parentRef:
+                            description: |-
+                              ParentRef is used to identify the parent resource that this status
+                              is associated with. It is used to match the InferencePool with the parent
+                              resource, such as a Gateway.
+                            properties:
+                              group:
+                                default: gateway.networking.k8s.io
+                                description: |-
+                                  Group is the group of the referent API object. When unspecified, the referent is assumed
+                                  to be in the "gateway.networking.k8s.io" API group.
+                                maxLength: 253
+                                minLength: 0
+                                pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                type: string
+                              kind:
+                                default: Gateway
+                                description: |-
+                                  Kind is the kind of the referent API object. When unspecified, the referent is assumed
+                                  to be a "Gateway" kind.
+                                maxLength: 63
+                                minLength: 1
+                                pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+                                type: string
+                              name:
+                                description: Name is the name of the referent API
+                                  object.
+                                maxLength: 253
+                                minLength: 1
+                                type: string
+                              namespace:
+                                description: |-
+                                  Namespace is the namespace of the referenced object. When unspecified, the local
+                                  namespace is inferred.
+
+                                  Note that when a namespace different than the local namespace is specified,
+                                  a ReferenceGrant object is required in the referent namespace to allow that
+                                  namespace's owner to accept the reference. See the ReferenceGrant
+                                  documentation for details: https://gateway-api.sigs.k8s.io/api-types/referencegrant/
+                                maxLength: 63
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                type: string
+                            required:
+                            - name
+                            type: object
+                        required:
+                        - parentRef
+                        type: object
+                      type: array
+                      x-kubernetes-list-type: atomic
+                  required:
+                  - name
+                  type: object
+                maxItems: 8
+                type: array
+                x-kubernetes-list-map-keys:
+                - name
+                x-kubernetes-list-type: map
+            required:
+            - controllers
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+status:
+  acceptedNames:
+    kind: ""
+    plural: ""
+  conditions: null
+  storedVersions: null
diff --git a/config/crd/bases/inference.networking.x-k8s.io_inferencepools.yaml b/config/crd/bases/inference.networking.x-k8s.io_inferencepools.yaml
index ef73c4a..e0a15b3 100644
--- a/config/crd/bases/inference.networking.x-k8s.io_inferencepools.yaml
+++ b/config/crd/bases/inference.networking.x-k8s.io_inferencepools.yaml
@@ -4,7 +4,6 @@ metadata:
   annotations:
     api-approved.kubernetes.io: unapproved, experimental-only
     inference.networking.k8s.io/bundle-version: main-dev
-  creationTimestamp: null
   name: inferencepools.inference.networking.x-k8s.io
 spec:
   group: inference.networking.x-k8s.io
diff --git a/config/manifests/bbr-example/httproute_bbr.yaml b/config/manifests/bbr-example/httproute_bbr.yaml
new file mode 100644
index 0000000..8702546
--- /dev/null
+++ b/config/manifests/bbr-example/httproute_bbr.yaml
@@ -0,0 +1,51 @@
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: llm-llama-route
+spec:
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: inference-gateway
+  rules:
+  - backendRefs:
+    - group: inference.networking.k8s.io
+      kind: InferencePool
+      name: vllm-llama3-8b-instruct
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+      headers:
+        - type: Exact
+          name: X-Gateway-Model-Name
+          value: 'meta-llama/Llama-3.1-8B-Instruct'
+    timeouts:
+      request: 300s
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: llm-phi4-route
+spec:
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: inference-gateway
+  rules:
+  - backendRefs:
+    - group: inference.networking.k8s.io
+      kind: InferencePool
+      name: vllm-phi4-mini-instruct
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+      headers:
+        - type: Exact
+          name: X-Gateway-Model-Name
+          value: 'microsoft/Phi-4-mini-instruct'
+    timeouts:
+      request: 300s
+---
diff --git a/config/manifests/bbr-example/vllm-phi4-mini.yaml b/config/manifests/bbr-example/vllm-phi4-mini.yaml
new file mode 100644
index 0000000..7f7827c
--- /dev/null
+++ b/config/manifests/bbr-example/vllm-phi4-mini.yaml
@@ -0,0 +1,88 @@
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: phi4-mini
+  namespace: default
+spec:
+  accessModes:
+  - ReadWriteOnce
+  resources:
+    requests:
+      storage: 20Gi
+  volumeMode: Filesystem
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: phi4-mini
+  namespace: default
+  labels:
+    app: phi4-mini
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: phi4-mini
+  template:
+    metadata:
+      labels:
+        app: phi4-mini
+    spec:
+      volumes:
+      - name: cache-volume
+        persistentVolumeClaim:
+          claimName: phi4-mini
+      containers:
+      - name: phi4-mini
+        image: vllm/vllm-openai:latest
+        command: ["/bin/sh", "-c"]
+        args: [
+          "vllm serve microsoft/Phi-4-mini-instruct --trust-remote-code --enable-chunked-prefill" 
+        ]
+        env:
+        - name: HUGGING_FACE_HUB_TOKEN
+          valueFrom:
+            secretKeyRef:
+              name: hf-token
+              key: token
+        ports:
+        - containerPort: 8000
+        resources:
+          limits:
+            nvidia.com/gpu: "1"
+          requests:
+            nvidia.com/gpu: "1"
+        volumeMounts:
+        - mountPath: /root/.cache/huggingface
+          name: cache-volume
+        livenessProbe:
+          httpGet:
+            path: /health
+            port: 8000
+          initialDelaySeconds: 600
+          periodSeconds: 10
+        readinessProbe:
+          httpGet:
+            path: /health
+            port: 8000
+          initialDelaySeconds: 600
+          periodSeconds: 5
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: phi4-mini
+  namespace: default
+spec:
+  ports:
+  - name: http-phi4-mini
+    port: 80
+    protocol: TCP
+    targetPort: 8000
+  # The label selector should match the deployment labels & it is useful for prefix caching feature
+  selector:
+    app: phi4-mini
+  sessionAffinity: None
+  type: ClusterIP
+
diff --git a/config/manifests/gateway/agentgateway/httproute.yaml b/config/manifests/gateway/agentgateway/httproute.yaml
index 18e90ce..18c4507 100644
--- a/config/manifests/gateway/agentgateway/httproute.yaml
+++ b/config/manifests/gateway/agentgateway/httproute.yaml
@@ -9,7 +9,7 @@ spec:
     name: inference-gateway
   rules:
   - backendRefs:
-    - group: inference.networking.x-k8s.io
+    - group: inference.networking.k8s.io
       kind: InferencePool
       name: vllm-llama3-8b-instruct
     matches:
diff --git a/config/manifests/gateway/envoyaigateway/gateway.yaml b/config/manifests/gateway/envoyaigateway/gateway.yaml
new file mode 100644
index 0000000..1a53641
--- /dev/null
+++ b/config/manifests/gateway/envoyaigateway/gateway.yaml
@@ -0,0 +1,17 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+  name: envoy-ai-gateway
+spec:
+  controllerName: gateway.envoyproxy.io/gatewayclass-controller
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: inference-gateway
+spec:
+  gatewayClassName: envoy-ai-gateway
+  listeners:
+    - name: http
+      protocol: HTTP
+      port: 80
diff --git a/config/manifests/gateway/envoyaigateway/httproute.yaml b/config/manifests/gateway/envoyaigateway/httproute.yaml
new file mode 100644
index 0000000..e685940
--- /dev/null
+++ b/config/manifests/gateway/envoyaigateway/httproute.yaml
@@ -0,0 +1,20 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: llm-route
+spec:
+  parentRefs:
+    - group: gateway.networking.k8s.io
+      kind: Gateway
+      name: inference-gateway
+  rules:
+    - backendRefs:
+        - group: inference.networking.k8s.io
+          kind: InferencePool
+          name: vllm-llama3-8b-instruct
+      matches:
+        - path:
+            type: PathPrefix
+            value: /
+      timeouts:
+        request: 300s
diff --git a/config/manifests/gateway/gke/gcp-backend-policy.yaml b/config/manifests/gateway/gke/gcp-backend-policy.yaml
deleted file mode 100644
index 9367865..0000000
--- a/config/manifests/gateway/gke/gcp-backend-policy.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-apiVersion: networking.gke.io/v1
-kind: GCPBackendPolicy
-metadata:
-  name: inferencepool-backend-policy
-spec:
-  targetRef:
-    group: "inference.networking.k8s.io"
-    kind: InferencePool
-    name: vllm-llama3-8b-instruct
-  default:
-    timeoutSec: 300
-    logging:
-      enabled: true
diff --git a/config/manifests/gateway/gke/healthcheck.yaml b/config/manifests/gateway/gke/healthcheck.yaml
deleted file mode 100644
index c9abb69..0000000
--- a/config/manifests/gateway/gke/healthcheck.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-kind: HealthCheckPolicy
-apiVersion: networking.gke.io/v1
-metadata:
-  name: health-check-policy
-  namespace: default
-spec:
-  targetRef:
-    group: "inference.networking.k8s.io"
-    kind: InferencePool
-    name: vllm-llama3-8b-instruct
-  default:
-    config:
-      type: HTTP
-      httpHealthCheck:
-          requestPath: /health
-          port: 8000
diff --git a/config/manifests/gateway/istio/httproute.yaml b/config/manifests/gateway/istio/httproute.yaml
index 18e90ce..18c4507 100644
--- a/config/manifests/gateway/istio/httproute.yaml
+++ b/config/manifests/gateway/istio/httproute.yaml
@@ -9,7 +9,7 @@ spec:
     name: inference-gateway
   rules:
   - backendRefs:
-    - group: inference.networking.x-k8s.io
+    - group: inference.networking.k8s.io
       kind: InferencePool
       name: vllm-llama3-8b-instruct
     matches:
diff --git a/config/manifests/gateway/kgateway/httproute.yaml b/config/manifests/gateway/kgateway/httproute.yaml
index 18e90ce..18c4507 100644
--- a/config/manifests/gateway/kgateway/httproute.yaml
+++ b/config/manifests/gateway/kgateway/httproute.yaml
@@ -9,7 +9,7 @@ spec:
     name: inference-gateway
   rules:
   - backendRefs:
-    - group: inference.networking.x-k8s.io
+    - group: inference.networking.k8s.io
       kind: InferencePool
       name: vllm-llama3-8b-instruct
     matches:
diff --git a/config/manifests/inferencepool-resources.yaml b/config/manifests/inferencepool-resources.yaml
deleted file mode 100644
index a3eba55..0000000
--- a/config/manifests/inferencepool-resources.yaml
+++ /dev/null
@@ -1,183 +0,0 @@
-# Note: If you change this file, please also change:
-#  - ./test/testdata/inferencepool-e2e.yaml
-#  - ./conformance/resources/manifests/manifests.yaml
-#  - ./site-src/guides/inferencepool-rollout.md
----
-apiVersion: inference.networking.k8s.io/v1
-kind: InferencePool
-metadata:
-  name: vllm-llama3-8b-instruct
-spec:
-  targetPorts:
-    - number: 8000
-  selector:
-    matchLabels:
-      app: vllm-llama3-8b-instruct
-  extensionRef:
-    name: vllm-llama3-8b-instruct-epp
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: vllm-llama3-8b-instruct-epp
-  namespace: default
-spec:
-  selector:
-    app: vllm-llama3-8b-instruct-epp
-  ports:
-    - protocol: TCP
-      port: 9002
-      targetPort: 9002
-      appProtocol: http2
-  type: ClusterIP
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: vllm-llama3-8b-instruct-epp
-  namespace: default
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: vllm-llama3-8b-instruct-epp
-  namespace: default
-  labels:
-    app: vllm-llama3-8b-instruct-epp
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: vllm-llama3-8b-instruct-epp
-  template:
-    metadata:
-      labels:
-        app: vllm-llama3-8b-instruct-epp
-    spec:
-      serviceAccountName: vllm-llama3-8b-instruct-epp
-      # Conservatively, this timeout should mirror the longest grace period of the pods within the pool
-      terminationGracePeriodSeconds: 130
-      containers:
-      - name: epp
-        image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/epp:main
-        imagePullPolicy: Always
-        args:
-        - --pool-name
-        - "vllm-llama3-8b-instruct"
-        - "--pool-namespace"
-        - "default"
-        - --v
-        - "4"
-        - --zap-encoder
-        - "json"
-        - --grpc-port
-        - "9002"
-        - --grpc-health-port
-        - "9003"
-        - "--config-file"
-        - "/config/default-plugins.yaml"
-        ports:
-        - containerPort: 9002
-        - containerPort: 9003
-        - name: metrics
-          containerPort: 9090
-        livenessProbe:
-          grpc:
-            port: 9003
-            service: inference-extension
-          initialDelaySeconds: 5
-          periodSeconds: 10
-        readinessProbe:
-          grpc:
-            port: 9003
-            service: inference-extension
-          initialDelaySeconds: 5
-          periodSeconds: 10
-        volumeMounts:
-        - name: plugins-config-volume
-          mountPath: "/config"
-      volumes:
-      - name: plugins-config-volume
-        configMap:
-          name: plugins-config
----
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: plugins-config
-  namespace: default
-data:
-  default-plugins.yaml: |
-    apiVersion: inference.networking.x-k8s.io/v1alpha1
-    kind: EndpointPickerConfig
-    plugins:
-    - type: queue-scorer
-    - type: kv-cache-utilization-scorer
-    - type: prefix-cache-scorer
-    schedulingProfiles:
-    - name: default
-      plugins:
-      - pluginRef: queue-scorer
-      - pluginRef: kv-cache-utilization-scorer
-      - pluginRef: prefix-cache-scorer
----
-kind: Role
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: pod-read
-  namespace: default
-rules:
-- apiGroups: [ "inference.networking.x-k8s.io" ]
-  resources: [ "inferenceobjectives", "inferencepools" ]
-  verbs: [ "get", "watch", "list" ]
-- apiGroups: [ "inference.networking.k8s.io" ]
-  resources: [ "inferencepools" ]
-  verbs: [ "get", "watch", "list" ]
-- apiGroups: [ "" ]
-  resources: [ "pods" ]
-  verbs: [ "get", "watch", "list" ]
----
-kind: RoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: pod-read-binding
-  namespace: default
-subjects:
-- kind: ServiceAccount
-  name: vllm-llama3-8b-instruct-epp
-  namespace: default
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: Role
-  name: pod-read
----
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: auth-reviewer
-rules:
-- apiGroups:
-  - authentication.k8s.io
-  resources:
-  - tokenreviews
-  verbs:
-  - create
-- apiGroups:
-  - authorization.k8s.io
-  resources:
-  - subjectaccessreviews
-  verbs:
-  - create
----
-kind: ClusterRoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: auth-reviewer-binding
-subjects:
-- kind: ServiceAccount
-  name: vllm-llama3-8b-instruct-epp
-  namespace: default
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: ClusterRole
-  name: auth-reviewer
diff --git a/config/manifests/regression-testing/vllm/multi-lora-deployment.yaml b/config/manifests/regression-testing/vllm/multi-lora-deployment.yaml
index 114cd99..9c02d35 100644
--- a/config/manifests/regression-testing/vllm/multi-lora-deployment.yaml
+++ b/config/manifests/regression-testing/vllm/multi-lora-deployment.yaml
@@ -14,7 +14,7 @@ spec:
     spec:
       containers:
         - name: vllm
-          image: "vllm/vllm-openai:latest"
+          image: "vllm/vllm-openai:v0.8.5"
           imagePullPolicy: Always
           command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
           args:
diff --git a/config/manifests/vllm/cpu-deployment.yaml b/config/manifests/vllm/cpu-deployment.yaml
index 3e38d4e..8b759d3 100644
--- a/config/manifests/vllm/cpu-deployment.yaml
+++ b/config/manifests/vllm/cpu-deployment.yaml
@@ -14,7 +14,7 @@ spec:
     spec:
       containers:
         - name: lora
-          image: "public.ecr.aws/q9t5s3a7/vllm-cpu-release-repo:latest" # formal images can be found in https://gallery.ecr.aws/q9t5s3a7/vllm-cpu-release-repo
+          image: "public.ecr.aws/q9t5s3a7/vllm-cpu-release-repo:v0.8.5" # formal images can be found in https://gallery.ecr.aws/q9t5s3a7/vllm-cpu-release-repo
           imagePullPolicy: Always
           command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
           args:
diff --git a/config/manifests/vllm/gpu-deployment.yaml b/config/manifests/vllm/gpu-deployment.yaml
index 16f9388..7ae591a 100644
--- a/config/manifests/vllm/gpu-deployment.yaml
+++ b/config/manifests/vllm/gpu-deployment.yaml
@@ -14,7 +14,7 @@ spec:
     spec:
       containers:
         - name: vllm
-          image: "vllm/vllm-openai:latest"
+          image: "vllm/vllm-openai:v0.8.5"
           imagePullPolicy: Always
           command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
           args:
diff --git a/config/manifests/vllm/sim-deployment.yaml b/config/manifests/vllm/sim-deployment.yaml
index 17b6891..2415c10 100644
--- a/config/manifests/vllm/sim-deployment.yaml
+++ b/config/manifests/vllm/sim-deployment.yaml
@@ -14,7 +14,7 @@ spec:
     spec:
       containers:
       - name: vllm-sim
-        image: ghcr.io/llm-d/llm-d-inference-sim:v0.3.0
+        image: ghcr.io/llm-d/llm-d-inference-sim:v0.5.0
         imagePullPolicy: Always
         args:
         - --model
diff --git a/conformance/conformance.go b/conformance/conformance.go
index 6aebd69..5d94197 100644
--- a/conformance/conformance.go
+++ b/conformance/conformance.go
@@ -134,12 +134,7 @@ func DefaultOptions(t *testing.T) confsuite.ConformanceOptions {
 		*confflags.ImplementationContact,
 	)
 
-	// Inference Extension Specific Report Fields
-	inferenceExtensionVersion := "v0.3.0"
-	_ = inferenceExtensionVersion // Avoid unused variable error until implemented
-
 	baseManifestsValue := "resources/base.yaml"
-
 	opts := confsuite.ConformanceOptions{
 		Client:               c,
 		ClientOptions:        clientOptions,
@@ -166,7 +161,6 @@ func DefaultOptions(t *testing.T) confsuite.ConformanceOptions {
 		// TODO: Add the inference extension specific fields to ConformanceOptions struct if needed,
 		// or handle them during report generation.
 		// GatewayAPIInferenceExtensionChannel: inferenceExtensionChannel,
-		// GatewayAPIInferenceExtensionVersion: inferenceExtensionVersion,
 	}
 
 	// Populate SupportedFeatures based on the GatewayLayerProfile.
@@ -197,6 +191,8 @@ func RunConformance(t *testing.T) {
 // RunConformanceWithOptions runs the Inference Extension conformance tests with specific options.
 func RunConformanceWithOptions(t *testing.T, opts confsuite.ConformanceOptions) {
 	t.Helper()
+	ctx := context.Background()
+
 	t.Logf("Running Inference Extension conformance tests with GatewayClass %s", opts.GatewayClassName)
 	logDebugf(t, opts.Debug, "RunConformanceWithOptions: BaseManifests path being used by opts: %q", opts.BaseManifests)
 
@@ -209,19 +205,28 @@ func RunConformanceWithOptions(t *testing.T, opts confsuite.ConformanceOptions)
 	cSuite, err := confsuite.NewConformanceTestSuite(opts)
 	require.NoError(t, err, "error initializing conformance suite")
 
-	SetupConformanceTestSuite(t, cSuite, opts, tests.ConformanceTests)
-
+	installedCRDs := &apiextensionsv1.CustomResourceDefinitionList{}
+	err = opts.Client.List(ctx, installedCRDs)
+	require.NoError(t, err, "error getting installedCRDs")
+	apiVersion, err := getGatewayInferenceExtentionVersion(installedCRDs.Items)
+	if err != nil {
+		if opts.AllowCRDsMismatch {
+			apiVersion = "UNDEFINED"
+		} else {
+			require.NoError(t, err, "error getting the gateway ineference extension version")
+		}
+	}
+	SetupConformanceTestSuite(ctx, t, cSuite, opts, tests.ConformanceTests)
 	t.Log("Running Inference Extension conformance tests against all registered tests")
 	err = cSuite.Run(t, tests.ConformanceTests)
 	require.NoError(t, err, "error running conformance tests")
 
-	// Generate and write the report if requested.
 	if opts.ReportOutputPath != "" {
 		t.Log("Generating Inference Extension conformance report")
 		report, err := cSuite.Report() // Use the existing report generation logic.
 		require.NoError(t, err, "error generating conformance report")
 		inferenceReport := GatewayAPIInferenceExtensionConformanceReport{
-			GatewayAPIInferenceExtensionVersion: version.BundleVersion,
+			GatewayAPIInferenceExtensionVersion: apiVersion,
 			ConformanceReport:                   *report,
 		}
 		err = inferenceReport.WriteReport(t.Logf, opts.ReportOutputPath)
@@ -229,7 +234,7 @@ func RunConformanceWithOptions(t *testing.T, opts confsuite.ConformanceOptions)
 	}
 }
 
-func SetupConformanceTestSuite(t *testing.T, suite *confsuite.ConformanceTestSuite, opts confsuite.ConformanceOptions, tests []confsuite.ConformanceTest) {
+func SetupConformanceTestSuite(ctx context.Context, t *testing.T, suite *confsuite.ConformanceTestSuite, opts confsuite.ConformanceOptions, tests []confsuite.ConformanceTest) {
 	suite.Applier.ManifestFS = suite.ManifestFS
 	if suite.RunTest != "" {
 		idx := slices.IndexFunc(tests, func(t confsuite.ConformanceTest) bool {
@@ -257,13 +262,31 @@ func SetupConformanceTestSuite(t *testing.T, suite *confsuite.ConformanceTestSui
 	}
 	apikubernetes.NamespacesMustBeReady(t, suite.Client, suite.TimeoutConfig, namespaces)
 
-	ensureGatewayAvailableAndReady(t, suite.Client, opts, resources.PrimaryGatewayNN)
-	ensureGatewayAvailableAndReady(t, suite.Client, opts, resources.SecondaryGatewayNN)
+	ensureGatewayAvailableAndReady(ctx, t, suite.Client, opts, resources.PrimaryGatewayNN)
+	ensureGatewayAvailableAndReady(ctx, t, suite.Client, opts, resources.SecondaryGatewayNN)
+}
+
+func getGatewayInferenceExtentionVersion(crds []apiextensionsv1.CustomResourceDefinition) (string, error) {
+	var inferenceVersion string
+	for _, crd := range crds {
+		v, okv := crd.Annotations[version.BundleVersionAnnotation]
+		if !okv {
+			continue
+		}
+		if inferenceVersion != "" && v != inferenceVersion {
+			return "", errors.New("multiple gateway api inference extension CRDs versions detected")
+		}
+		inferenceVersion = v
+	}
+	if inferenceVersion == "" {
+		return "", errors.New("no gateway api inference extension CRDs with the proper annotations found in the cluster")
+	}
+	return inferenceVersion, nil
 }
 
 // ensureGatewayAvailableAndReady polls for the specified Gateway to exist and become ready
 // with an address and programmed condition.
-func ensureGatewayAvailableAndReady(t *testing.T, k8sClient client.Client, opts confsuite.ConformanceOptions, gatewayNN types.NamespacedName) {
+func ensureGatewayAvailableAndReady(ctx context.Context, t *testing.T, k8sClient client.Client, opts confsuite.ConformanceOptions, gatewayNN types.NamespacedName) {
 	t.Helper()
 
 	t.Logf("Attempting to fetch Gateway %s/%s.", gatewayNN.Namespace, gatewayNN.Name)
@@ -277,7 +300,6 @@ func ensureGatewayAvailableAndReady(t *testing.T, k8sClient client.Client, opts
 
 	logDebugf(t, opts.Debug, "Waiting up to %v for Gateway object %s/%s to appear after manifest application...", waitForGatewayCreationTimeout, gatewayNN.Namespace, gatewayNN.Name)
 
-	ctx := context.TODO()
 	pollErr := wait.PollUntilContextTimeout(ctx, extTimeoutConf.GatewayObjectPollInterval, waitForGatewayCreationTimeout, true, func(pollCtx context.Context) (bool, error) {
 		fetchErr := k8sClient.Get(pollCtx, gatewayNN, gw)
 		if fetchErr == nil {
diff --git a/conformance/reports/v0.5.1/gateway/ack-gateway/README.md b/conformance/reports/v0.5.1/gateway/ack-gateway/README.md
new file mode 100644
index 0000000..a25a222
--- /dev/null
+++ b/conformance/reports/v0.5.1/gateway/ack-gateway/README.md
@@ -0,0 +1,51 @@
+# ACK (AlibabaCloud Container Service for Kubernetes) Gateway with Inference Extension
+
+## Table of Contents
+
+| Extension Version Tested | Profile Tested | Implementation Version | Mode    | Report                                                                     |
+|--------------------------|----------------|------------------------|---------|----------------------------------------------------------------------------|
+| v0.5.1                  | Gateway        | v1.4.0-apsara.3         | default | [v1.4.0-apsara.3 Gateway report](./v1.4.0-apsara.3-gateway-report.yaml) |
+
+## Reproduce
+
+ACK Gateway with Inference Extension conformance report can be reproduced by the following steps.
+
+1. Create an ACK managed cluster following [guide](https://www.alibabacloud.com/help/en/ack/ack-managed-and-ack-dedicated/user-guide/create-an-ack-managed-cluster-2/).
+
+2. Install ACK Gateway with Inference Extension following Step 2 in [documentation](https://www.alibabacloud.com/help/en/cs/user-guide/intelligent-routing-and-traffic-management-with-ack-gateway-inference-extension).
+
+3. Open `SELF_HOST_EPP` mode for the Gateway controller with following command:
+    ```
+    kubectl patch deployment envoy-gateway -n envoy-gateway-system --type='json' -p='[
+    {
+        "op": "add",
+        "path": "/spec/template/spec/containers/0/env/-",
+        "value": {
+          "name": "SELF_HOST_EPP",
+          "value": "true"
+        }
+      },
+      {
+        "op": "add",
+        "path": "/spec/template/spec/containers/1/env/-",
+        "value": {
+          "name": "SELF_HOST_EPP",
+          "value": "true"
+        }
+      }
+    ]'
+    ```
+
+4. Run the following command from within the [Gateway API inference extension repo](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/v0.5.1).
+
+    ```
+    go test -timeout 30m ./conformance -v -args \
+        --gateway-class=ack-gateway \
+        --conformance-profiles=Gateway \
+        --organization=AlibabaCloud \
+        --project=ack-gateway-with-inference-extension \
+        --url=https://www.alibabacloud.com/help/en/cs/user-guide/gateway-with-inference-extension-overview \
+        --version=v1.4.0-apsara.3 \
+        --contact=https://smartservice.console.aliyun.com/service/create-ticket \
+        --report-output="/path/to/report"
+    ```
diff --git a/conformance/reports/v0.5.1/gateway/ack-gateway/v1.4.0-apsara.3-gateway-report.yaml b/conformance/reports/v0.5.1/gateway/ack-gateway/v1.4.0-apsara.3-gateway-report.yaml
new file mode 100644
index 0000000..266b023
--- /dev/null
+++ b/conformance/reports/v0.5.1/gateway/ack-gateway/v1.4.0-apsara.3-gateway-report.yaml
@@ -0,0 +1,23 @@
+GatewayAPIInferenceExtensionVersion: v0.5.1
+apiVersion: gateway.networking.k8s.io/v1
+date: "2025-08-18T18:15:11+08:00"
+gatewayAPIChannel: experimental
+gatewayAPIVersion: v1.3.0
+implementation:
+  contact:
+  - https://smartservice.console.aliyun.com/service/create-ticket
+  organization: AlibabaCloud
+  project: ack-gateway-with-inference-extension
+  url: https://www.alibabacloud.com/help/en/cs/user-guide/gateway-with-inference-extension-overview
+  version: v1.4.0-apsara.3
+kind: ConformanceReport
+mode: default
+profiles:
+- core:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 9
+      Skipped: 0
+  name: Gateway
+  summary: Core tests succeeded.
\ No newline at end of file
diff --git a/conformance/reports/v0.5.1/gateway/kubvernor/README.md b/conformance/reports/v0.5.1/gateway/kubvernor/README.md
new file mode 100644
index 0000000..62b6545
--- /dev/null
+++ b/conformance/reports/v0.5.1/gateway/kubvernor/README.md
@@ -0,0 +1,12 @@
+# Kubvernor Rust Gateway
+
+## Table of Contents
+
+| Extension Version Tested | Profile Tested | Implementation Version | Mode    | Report                                                                |
+|--------------------------|----------------|------------------------|---------|-----------------------------------------------------------------------|
+| v0.5.1                   | Gateway        | [0.1.1](https://github.com/kubvernor/kubvernor/releases/tag/0.1.1)                  | default | [Conformance report](./kubvernor-inference-conformance-output-0.1.1.yaml) |
+
+## Reproduce
+
+To reproduce Kubvernor conformance report follow [README](https://github.com/kubvernor/kubvernor/blob/0.1.1/README.md)
+
diff --git a/conformance/reports/v0.5.1/gateway/kubvernor/kubvernor-inference-conformance-output-0.1.1.yaml b/conformance/reports/v0.5.1/gateway/kubvernor/kubvernor-inference-conformance-output-0.1.1.yaml
new file mode 100644
index 0000000..1595f49
--- /dev/null
+++ b/conformance/reports/v0.5.1/gateway/kubvernor/kubvernor-inference-conformance-output-0.1.1.yaml
@@ -0,0 +1,23 @@
+GatewayAPIInferenceExtensionVersion: v0.5.1
+apiVersion: gateway.networking.k8s.io/v1
+date: "2025-08-25T15:42:29+01:00"
+gatewayAPIChannel: standard
+gatewayAPIVersion: v1.2.1
+implementation:
+  contact:
+    - https://github.com/kubvernor/kubvernor
+  organization: kubvernor
+  project: kubvernor
+  url: https://github.com/kubvernor/kubvernor
+  version: 0.1.1
+kind: ConformanceReport
+mode: default
+profiles:
+  - core:
+      result: success
+      statistics:
+        Failed: 0
+        Passed: 9
+        Skipped: 0
+    name: Gateway
+    summary: Core tests succeeded.
diff --git a/conformance/reports/v1.0.0/gateway/kgateway/README.md b/conformance/reports/v1.0.0/gateway/kgateway/README.md
new file mode 100644
index 0000000..c64981f
--- /dev/null
+++ b/conformance/reports/v1.0.0/gateway/kgateway/README.md
@@ -0,0 +1,78 @@
+# Kgateway
+
+This guide provides the steps for running Gateway conformance tests against [kgateway](https://kgateway.dev/) with the default
+([Envoy](https://www.envoyproxy.io/)) data plane.
+
+## Table of Contents
+
+| Extension Version Tested | Profile Tested | Implementation Version | Mode    | Report                                                                     |
+|--------------------------|----------------|------------------------|---------|----------------------------------------------------------------------------|
+| v1.0.0                   | Gateway        | v2.1.0-main            | default | [v2.1.0-main report](./inference-v2.1.0-main-report.yaml)   |
+
+## Reproduce
+
+This is a mirror of the kgateway [inference conformance GHA workflow](https://github.com/kgateway-dev/kgateway/blob/v2.0.x/.github/actions/kube-inference-extension-conformance-tests/action.yaml).
+
+### Prerequisites
+
+In order to run the conformance tests, the following prerequisites must be met:
+
+- The [kubectl](https://kubernetes.io/docs/tasks/tools/) command-line tool installed and configured for the active cluster context.
+- The [helm](https://github.com/helm/helm), [git](https://git-scm.com/downloads), and [make](https://www.gnu.org/software/make/) command-line tools installed.
+
+### Steps
+
+1. Set the environment variables use by the proceeding steps:
+
+   ```sh
+   # The kgateway version
+   export VERSION=v2.1.0-main
+   # Skip building and loading the kgateway images
+   export SKIP_DOCKER=true
+   # Install Gateway API and Inference Extension CRDs
+   export CONFORMANCE=true
+   ```
+
+2. Clone the kgateway repository and checkout the release:
+
+   ```sh
+   git clone -b $VERSION https://github.com/kgateway-dev/kgateway.git && cd kgateway
+   ```
+
+3. Create a KinD cluster:
+
+   ```sh
+   make kind-setup
+   ```
+
+4. Install the kgateway CRDs:
+
+   ```sh
+   helm upgrade -i --create-namespace --namespace kgateway-system \
+   --version $VERSION kgateway-crds oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds
+   ```
+
+5. Install kgateway with Inference Extension enabled:
+
+   ```sh
+   helm upgrade -i --namespace kgateway-system --version $VERSION \
+   kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway --set inferenceExtension.enabled=true
+   ```
+
+6. Wait for the kgateway rollout to complete:
+
+   ```sh
+   kubectl rollout status deploy/kgateway -n kgateway-system
+   ```
+
+7. Run the conformance tests:
+
+   ```sh
+   make gie-conformance
+   ```
+
+8. View and verify the conformance report:
+
+   ```sh
+   cat _test/conformance/inference-$VERSION-report.yaml
+   ```
diff --git a/conformance/reports/v1.0.0/gateway/kgateway/agentgateway/README.md b/conformance/reports/v1.0.0/gateway/kgateway/agentgateway/README.md
new file mode 100644
index 0000000..7f35d2b
--- /dev/null
+++ b/conformance/reports/v1.0.0/gateway/kgateway/agentgateway/README.md
@@ -0,0 +1,79 @@
+# Kgateway with agentgateway
+
+This guide provides the steps for running Gateway conformance tests against [kgateway](https://kgateway.dev/) with the
+([agentgateway](https://agentgateway.dev/)) data plane.
+
+## Table of Contents
+
+| Extension Version Tested | Profile Tested | Implementation Version | Mode    | Report                                                                     |
+|--------------------------|----------------|------------------------|---------|----------------------------------------------------------------------------|
+| v1.0.0                   | Gateway        | v2.1.0-main            | default | [v2.1.0-main report](./inference-v2.1.0-main-report.yaml)   |
+
+## Reproduce
+
+This is a mirror of the kgateway [conformance test] with the default (Envoy) data plane [conformance test](../README.md).
+
+### Prerequisites
+
+In order to run the conformance tests, the following prerequisites must be met:
+
+- The [kubectl](https://kubernetes.io/docs/tasks/tools/) command-line tool installed and configured for the active cluster context.
+- The [helm](https://github.com/helm/helm), [git](https://git-scm.com/downloads), and [make](https://www.gnu.org/software/make/) command-line tools installed.
+
+### Steps
+
+1. Set the environment variables use by the proceeding steps:
+
+   ```sh
+   # The kgateway version
+   export VERSION=v2.1.0-main
+   # Skip building and loading the kgateway images
+   export SKIP_DOCKER=true
+   # Install Gateway API and Inference Extension CRDs
+   export CONFORMANCE=true
+   ```
+
+2. Clone the kgateway repository and checkout the release:
+
+   ```sh
+   git clone -b $VERSION https://github.com/kgateway-dev/kgateway.git && cd kgateway
+   ```
+
+3. Create a KinD cluster:
+
+   ```sh
+   make kind-setup
+   ```
+
+4. Install the kgateway CRDs:
+
+   ```sh
+   helm upgrade -i --create-namespace --namespace kgateway-system \
+   --version $VERSION kgateway-crds oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds
+   ```
+
+5. Install kgateway with Inference Extension and agentgateway enabled:
+
+   ```sh
+   helm upgrade -i --namespace kgateway-system --version $VERSION \
+   kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway \
+   --set inferenceExtension.enabled=true --set agentGateway.enabled=true
+   ```
+
+6. Wait for the kgateway rollout to complete:
+
+   ```sh
+   kubectl rollout status deploy/kgateway -n kgateway-system
+   ```
+
+7. Run the conformance tests:
+
+   ```sh
+   CONFORMANCE_GATEWAY_CLASS=agentgateway make gie-conformance
+   ```
+
+8. View and verify the conformance report:
+
+   ```sh
+   cat _test/conformance/inference-$VERSION-report.yaml
+   ```
diff --git a/conformance/reports/v1.0.0/gateway/kgateway/agentgateway/inference-v2.1.0-main-report.yaml b/conformance/reports/v1.0.0/gateway/kgateway/agentgateway/inference-v2.1.0-main-report.yaml
new file mode 100644
index 0000000..9e4063b
--- /dev/null
+++ b/conformance/reports/v1.0.0/gateway/kgateway/agentgateway/inference-v2.1.0-main-report.yaml
@@ -0,0 +1,23 @@
+GatewayAPIInferenceExtensionVersion: v1.0.0
+apiVersion: gateway.networking.k8s.io/v1
+date: "2025-09-14T10:03:01-07:01"
+gatewayAPIChannel: experimental
+gatewayAPIVersion: v1.3.0
+implementation:
+  contact:
+  - github.com/kgateway-dev/kgateway/issues/new/choose
+  organization: kgateway-dev
+  project: kgateway
+  url: github.com/kgateway-dev/kgateway
+  version: v2.1.0-main
+kind: ConformanceReport
+mode: default
+profiles:
+- core:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 9
+      Skipped: 0
+  name: Gateway
+  summary: Core tests succeeded.
diff --git a/conformance/reports/v1.0.0/gateway/kgateway/inference-v2.1.0-main-report.yaml b/conformance/reports/v1.0.0/gateway/kgateway/inference-v2.1.0-main-report.yaml
new file mode 100644
index 0000000..3bee5ac
--- /dev/null
+++ b/conformance/reports/v1.0.0/gateway/kgateway/inference-v2.1.0-main-report.yaml
@@ -0,0 +1,23 @@
+GatewayAPIInferenceExtensionVersion: v1.0.0
+apiVersion: gateway.networking.k8s.io/v1
+date: "2025-09-12T11:05:01-07:00"
+gatewayAPIChannel: experimental
+gatewayAPIVersion: v1.3.0
+implementation:
+  contact:
+  - github.com/kgateway-dev/kgateway/issues/new/choose
+  organization: kgateway-dev
+  project: kgateway
+  url: github.com/kgateway-dev/kgateway
+  version: v2.1.0-main
+kind: ConformanceReport
+mode: default
+profiles:
+- core:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 9
+      Skipped: 0
+  name: Gateway
+  summary: Core tests succeeded.
diff --git a/conformance/resources/base.yaml b/conformance/resources/base.yaml
index 5e00a69..a421f50 100644
--- a/conformance/resources/base.yaml
+++ b/conformance/resources/base.yaml
@@ -157,8 +157,10 @@ spec:
       app: primary-inference-model-server
   targetPorts:
     - number: 3000
-  extensionRef:
+  endpointPickerRef:
     name: primary-endpoint-picker-svc
+    port:
+      number: 9002
 ---
 # --- Primary Conformance EPP service Definition ---
 apiVersion: v1
@@ -198,7 +200,7 @@ spec:
       terminationGracePeriodSeconds: 130
       containers:
       - name: epp
-        image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/epp:main
+        image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/epp:v1.0.0
         imagePullPolicy: Always
         args:
         - --pool-name
@@ -249,12 +251,14 @@ metadata:
 spec:
   selector:
     matchLabels:
-      app: primary-inference-model-server
+      app: secondary-inference-model-server
   targetPorts:
     - number: 3000
-  extensionRef:
+  endpointPickerRef:
     name: secondary-endpoint-picker-svc
     failureMode: FailOpen
+    port:
+      number: 9002
 ---
 # --- Secondary Conformance EPP service Definition ---
 apiVersion: v1
@@ -294,7 +298,7 @@ spec:
       terminationGracePeriodSeconds: 130
       containers:
       - name: epp
-        image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/epp:main
+        image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/epp:v1.0.0
         imagePullPolicy: Always
         args:
         - --pool-name
diff --git a/conformance/resources/resourcename.go b/conformance/resources/resourcename.go
index 6f23840..4c0c7b4 100644
--- a/conformance/resources/resourcename.go
+++ b/conformance/resources/resourcename.go
@@ -34,8 +34,6 @@ const (
 
 	ModelServerPodReplicas    = 3
 	EndPointPickerPodReplicas = 1
-
-	InferenceObjName = "conformance-fake-model-server"
 )
 
 var (
diff --git a/conformance/utils/kubernetes/helpers.go b/conformance/utils/kubernetes/helpers.go
index 39301e3..b4018a7 100644
--- a/conformance/utils/kubernetes/helpers.go
+++ b/conformance/utils/kubernetes/helpers.go
@@ -105,7 +105,9 @@ func InferencePoolMustHaveCondition(t *testing.T, c client.Reader, poolNN types.
 			}
 
 			for _, parentStatus := range pool.Status.Parents {
-				if string(parentStatus.GatewayRef.Namespace) == gateway.Namespace && string(parentStatus.GatewayRef.Name) == gateway.Name {
+				if parentStatus.ParentRef.Namespace != "" &&
+					string(parentStatus.ParentRef.Namespace) == gateway.Namespace &&
+					string(parentStatus.ParentRef.Name) == gateway.Name {
 					if checkCondition(t, parentStatus.Conditions, expectedCondition) {
 						conditionFound = true
 						return true, nil
@@ -130,8 +132,11 @@ func InferencePoolMustHaveCondition(t *testing.T, c client.Reader, poolNN types.
 				debugMsg += " (No parent statuses reported)"
 			}
 			for i, parentStatus := range lastObservedPool.Status.Parents {
-				namespace := parentStatus.GatewayRef.Namespace
-				debugMsg += fmt.Sprintf("\n  Parent %d (Gateway: %s/%s):", i, namespace, parentStatus.GatewayRef.Name)
+				namespace := parentStatus.ParentRef.Namespace
+				if namespace == "" {
+					namespace = inferenceapi.Namespace(poolNN.Namespace) // Fallback to the pool's namespace
+				}
+				debugMsg += fmt.Sprintf("\n  Parent %d (Gateway: %s/%s):", i, namespace, parentStatus.ParentRef.Name)
 				if len(parentStatus.Conditions) == 0 {
 					debugMsg += " (No conditions reported for this parent)"
 				}
diff --git a/conformance/utils/traffic/traffic.go b/conformance/utils/traffic/traffic.go
index f53cc32..8acaefa 100644
--- a/conformance/utils/traffic/traffic.go
+++ b/conformance/utils/traffic/traffic.go
@@ -169,24 +169,56 @@ func waitForConvergeToExpected(
 	tlog.Logf(t, "Request passed")
 }
 
-// CompareRequestWithWildcardStatus compares requests with wildcard status code support.
-// It treats a single-digit expected code (e.g., 4) as a class wildcard (4xx),
-// while standard 3-digit codes are matched exactly.
-func CompareRequestWithWildcardStatus(t *testing.T, req *roundtripper.Request, cReq *roundtripper.CapturedRequest, cRes *roundtripper.CapturedResponse, expected gwhttp.ExpectedResponse) error {
-	if expected.Response.StatusCode < 1 || expected.Response.StatusCode >= 100 {
-		return gwhttp.CompareRequest(t, req, cReq, cRes, expected)
+// CompareRequestWithWildcardStatus compares requests allowing single-digit
+// status "classes" (e.g. 5 => any 5xx) via ExpectedResponse.Response.StatusCodes.
+// If no class wildcards are present, it defers to CompareRoundTrip.
+func CompareRequestWithWildcardStatus(
+	t *testing.T,
+	req *roundtripper.Request,
+	cReq *roundtripper.CapturedRequest,
+	cRes *roundtripper.CapturedResponse,
+	expected gwhttp.ExpectedResponse,
+) error {
+	// Separate specific status codes (>=100) from wildcard classes (1..9).
+	var wildcardClasses []int
+	var specificCodes []int
+	seenClass := map[int]struct{}{}
+	seenCode := map[int]struct{}{}
+
+	for _, sc := range expected.Response.StatusCodes {
+		switch {
+		case sc >= 100:
+			if _, ok := seenCode[sc]; !ok {
+				specificCodes = append(specificCodes, sc)
+				seenCode[sc] = struct{}{}
+			}
+		case sc >= 1 && sc <= 9:
+			if _, ok := seenClass[sc]; !ok {
+				wildcardClasses = append(wildcardClasses, sc)
+				seenClass[sc] = struct{}{}
+			}
+		}
 	}
 
-	expectedClass := expected.Response.StatusCode
+	// No wildcard classes? Defer to standard comparator.
+	if len(wildcardClasses) == 0 {
+		return gwhttp.CompareRoundTrip(t, req, cReq, cRes, expected)
+	}
+
+	// If the concrete status matches any wildcard class, materialize it and compare.
 	actualClass := cRes.StatusCode / 100
-	if expectedClass != actualClass {
-		return fmt.Errorf("expected status code class %dxx, but got %d", expectedClass, cRes.StatusCode)
+	for _, wc := range wildcardClasses {
+		if actualClass == wc {
+			modified := expected
+			// Keep any specific codes that were provided, but ensure the actual status is allowed.
+			modified.Response.StatusCodes = append(append([]int(nil), specificCodes...), cRes.StatusCode)
+			return gwhttp.CompareRoundTrip(t, req, cReq, cRes, modified)
+		}
 	}
 
-	// StatusCode Class matches; update status code on a copy to allow the standard comparator to pass.
-	modifiedExpected := expected
-	modifiedExpected.Response.StatusCode = cRes.StatusCode
-	return gwhttp.CompareRequest(t, req, cReq, cRes, modifiedExpected)
+	// Wildcards were provided but none matched the actual class—fail clearly.
+	return fmt.Errorf("expected status code class to be one of %vxx, got %d",
+		wildcardClasses, cRes.StatusCode)
 }
 
 // TODO: https://github.com/kubernetes-sigs/gateway-api-inference-extension/issues/1031
diff --git a/crd-ref-docs.yaml b/crd-ref-docs.yaml
index d00e6d0..5fefbff 100644
--- a/crd-ref-docs.yaml
+++ b/crd-ref-docs.yaml
@@ -4,7 +4,7 @@
 
 processor:
   ignoreTypes:
-    - "(InferencePool|InferenceObjective)List$"
+    - "(InferencePool|InferenceObjective|InferencePoolImport)List$"
   # RE2 regular expressions describing type fields that should be excluded from the generated documentation.
   ignoreFields:
     - "TypeMeta$"
diff --git a/docs/endpoint-picker.svg b/docs/endpoint-picker.svg
index 3ec8eed..6f4b9cf 100644
--- a/docs/endpoint-picker.svg
+++ b/docs/endpoint-picker.svg
@@ -1,3 +1,5 @@
-<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1452.6284042512102 785.1072998046875" width="1452.6284042512102" height="785.1072998046875"><!-- svg-source:excalidraw --><metadata></metadata><defs><style class="style-fonts">
-      @font-face { font-family: Excalifont; src: url(data:font/woff2;base64,d09GMgABAAAAAB04AA4AAAAAM5gAABzgAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbjUocgXIGYACBJBEICsx0uG0LYAABNgIkA4E8BCAFgxgHIBs+KKOitFNeRvZXB7wh3tQfwLtareM4EQSGXenHllydGFpS83eGbhpiiccToeH5ufXe/9v/i/qLYoNtbERuhIxeJDm6JR1goc2dgA1iFfaVmSgq54Un2niFXoXV8Pz/3/9v7nXOBXvDAyrQ30fz758CDT2OMOCwt02arti2uDmGviQMhTAGpX5o/i+nKV011z8zgsCCZdkOLdiLBQDLLpzSvh5773F9da5ix1kSGpK8rrPOAvBIUyiA/590q0/+76C1U62+SqUGy2+v+tUV/aSdaZ9E2ADLJMF29wRYs1OZTP5vv195EEsMjSgaCZVkGUKhlPdlgPsGs2Ewl2QeEodKenxMdhGxtp/2N3lpxE2BtpGtdeOWktbP8U7neBeqGy0h9FxI+SOfK912AAQAAwFAyC4uEBSC4H0BQKNlQNo/TMkG0puOtiYgfWiraQTS14rJLUCKBAAgHgVe7tpaAOUqAM7sIsthGASgikDmYcefM/l0/kPIAxh/AALDra/+532NQa/HT7aJp3W9dwHNaLwnYfzuB+q9PoCg8fIYpm3s/b2LhA2/C2itTgYUO36R50xGbfZ7Zzr+z6t6V4Wd/KzPgfIgkXnDIPFulPE3gz+jGojvDUe8F+P7WYK9XqZnhKw8AcBvl28VOMSpPc+ur+fmrZR/T3qWI4XidtMUVDRMbBwELh4+ARExCRk5Lyre1Pz4CxAomwujghB4RACATV0LVVwHAyDNCwCJBE5AbgM2TONDSAjRpXEUDAJcTELiLGwuE4OcCYEEPPRFru3xVU7ur2LOaejSXhQAJhbAp5wglPDhBiMHZQg1QxzmmCFSkNI2yoXqjRHixpi8Ng7lROzyWFDEL4oEBbgOFMIQG0NcjODbJxESwYgxlRSTqTBGg3EBcg5GkDAAAEMs+Y7LCM32EWQQufWJcnGymGvDpJC8peL1qa4C8D/aqltihiFIYXSLzhEjCO2MUyD35kGCFcBDSRwbn8paECokgPkHahagAzEiZHI9uQ6IO1Xt2pcazXB8EDBSXI0oxMKQJIYEHEQQmXWTXb3IKFmUfAAkb2YCz4V5A46hZS1n9jQwCBQ6xtS1RJ7lq6kbAGzpBsGv6/gp8jugCvhDCoeYpNdCQYF0Mn/BQkUxsrJzSuWSLY9bR49b9f20zWYp0mUZV2h7tcfHjr7z9u9efunFQ88ffLZP96E+CDZdUpYcgNAOKq0aDzB+ANbvsBXF0ZNERNXVWyG7htp1D3UJoZcGN7c8NY4cQZLZsz2zKrZa7h+tzEhvDef7iCLjWP6rrFyzVCbUpNB1mSWeAezI7aJke3qRM4wNnS3VzlZ/vJHeJm/MfiuFvLUIIx8Alwv66UswuYah48EtP7MzvNyfgdSUzkB0PdelfOWFtspblsOCAGj4eEFH85IEzV7l+cFcN9ts0ci0PKLRl4zUx/gA406Eh7J/DOKLpASTiQk10lb//7Blq829Hj35VzE2sqWAAY1YxSjW9LdHpRv6MTkc9g9f0ffJJvWuGEn7ZOs95iLHXVKSTJLl3QWe7hiq3ap/Vi/yOAKfyY1KWekbsv+ZbhoSmbD4pyS0XKPzxFNJqmlW0pIkJbh6FeApSDFeaR3ZFeZbFy5o3mkyNuoqkxtwxoPeGSYgUpFt2xgtgGMAkAvY9z2A39Q0mSYJrV90FwoYTBiAvSqLdzaLuWiyrcYnrFK0zD2aKUgF8YFzypfmsTp6vC8kNIhBTsLUGoGhnBArbmRI3cN4Cgankno5XOBkiq4m+Oqrl1SThDaDQnRjPkdDWqtZs6lGSOFqgvO/mbfzHHgpGVi7agX3FKt/912rEL5BWTwRF9ffsVxCHORyTnk4kAVUmikB0DVSWy3mmksbYjzPSUJnVE2TJ5QfTBE3Pqk+98c6VkjoOlgA24WKiWeonHFuuKy0gzfkoAQXpQeqqRls/w2AsMbXkjWacVQQ+gAwZSW4exdgQm6CE5B43qjWPfOOlbv820IYXf0xGSu3Prr3uKIn4W541XoKhnr5xzN+tLAqFQUZBVps4DSKMCLkmKf4cd4AtkfQnC5fbGU04lpRIElOJJAkSefohpHp5YzykGa4zInr2ricjGUIQ8vqdiVZknAJJGkJbTYDZzxF2LgYq8iObIwe6KaEj0GaVkpX9N1VWYC52El6e35ppZAO17yOQzp0DSnFpLoMwOsDNhKkjOKKbmRHGCPbFhy/dBNikm6eI2GhUqF6JJT8bQaD+maLNv8mHxoYgGVZXcuB9FCojT9kvsW1iGtlqh5JpqCNq02BmdO7beoNqYpwFTOMOQ5OKTnhLYzp77JoWSnst+WM65jrj7UpxsIp0TSqabh+3hQdX3lxRysKK8WJuSTfglTQ4a68DeBZHsa9wbWsOjQ3xecq1W+lZKSFN/rlMOqIEpRXy+P7tgeTY+usND1yrwQAni93l9CyPNj+NeMGJ3UmkDvV+RljMi/KMrYA1gGYUla/G07JphgO6VoVqxsfq5wbe2pYEMvzQS3cH51UU8TD5Ep983qiXvSPX6DvCZOyjCUKQ9AMTMnxL+U4p9szbVZ/9NXLxIlXUO98RyViRw2A9fqTJGnFtRCeJlRFkaF4G/m9KvoWBgvSbklOpFKBS/oYcgHzWceqAC7B1LUaifWTccubi0Wac6MbOi+9g3sXlQBXkda57Z+MiNJmpikoOG3BCRBrqyt35/vtjz6qKc1z6UlGSkdF4PbiLXnSNCFgo5uyX4EykbRWG+074TnQGFTACk1d1MgJnKBDO/zGSaZ7SJkY2VBNMJqY42VclV//I4Q1A1ILW0a1lPF0e5T1TsvWNp6OFgdLw9V7bNlmWxHfz+n4upCabTPZ0PjoQ099Pstngu20YrgoRrfLqSS/AguDfcqG5uD7QTnpXiT2sNLu3Hl3jzeyS1k18GUfZOiQmNBFmL5cFOs+Dj5PcqOFmSCOTU1ZIxIWmltYc5Yr9bOts3y+d5pGXIwMvISDvQ3R9JnsKB8E4xwHANL8Elv7JXO7x+1rSNFCIJbsycgS/7CQeobv67099pGW5BdXfKGXfzr78mr2aaY4V+uXzMSwlQShHa2toeyGFn1xRe6mlWNNitxRiQ0QsdlwqPMOXYjbnR/HJ3lKmzOMto/FfLt+mQYkrcuQzFnT5KuzXH9cx7TJb78gc0mWHNlZzxVhhX884TQeqLExrvPlbmW6otkFLiinvOfKTzaLuT4/uYXU+wKEJAl9ku6OKgBgRVINEqT4C62YlpOlam2RyQbt7cVJCVZleaVQbUU/TRlMjoEkl0n0go5LO/xcofaL/RfJdV3bRlf4iBwi31NIhlR1J9+bp4SFdX6F+DFJN7Toio6ujbkwvo3r8J+ujYgsCj3VUQMV0ffPYrHuCYx8aUE296+GEZ7Z/gvypUT6l/xi3ko3tWh2fIxjnHtK6xckLAqVhnhjNn/1Ftd/3eIGX3GTmiyOvwg8awjPQmg9/SwnNDI8bA6OWKYB8aQSMLldmqor89zribwhvhsXXGU9OyjyXAmEJprZ6pPYCM6JfT6/xPdFSFWFjZsodBkTgrzfVxDAnKoUiG6EVIaP+3uPsmN1S0+WnCHXVo1Z9bbp9/uD5SAkqUrBhnNODCVIsT2ofF2B1AIdExLdEoEBrN5sDmILtEFoIMlTjWSyX/7WjTj1VBK9IVZKIIh1gbe2KA+HdHyUo7Gt5E5T9IUAIDQf/C5vzrWoQ7faW0jl7+c9A5iE99uK83kKAmdArCtBA6SwLoPXF3CMk5/BchyHWPaKDk+hgW++fP+ePqfXaLNPpsU7JcEEQ4E8+FWtFDy6/9F6Mzi+0Uh+vXty79OH86EgYCDJmJSmlWsTgBF0FfQtr51LktfVhZiOq0UGRxhtQZgt7tH7a9zZiR4gZXCPpAUpkQUCEp/8sxAVrdWS61usyLvWJAwBPLyRV3NHNO+ZE/PVeY3+3tBsMZoLiQY5ISJzbDpNv1r7tO6OG0MFc3w5e5A0PpnNDEBPGMh6JRWUEEsYGQyg7tuMdLaV412YpE8/g8mqjGNCgVNI/gaHbQ2c6yQ8F3CRRZf285DyDnrS1SoTobuEkY3UQiFnO6nrZIjtCA9nBLRP5bOLFTClQ0a3l20m/CDW7nTMscHXlJyOB36GkfINd8sd9mg0f3eBdUQJSpwpbzGlIACkd7umDC9S+lB47px6wgvEOXc6bqEvl2FHCGYR8XCL1qML7dhPle1jR3hZQeXq+A7X+DC/y25EhzNZ+oi70gs2BOUVzeWT/CVzjYIBOUy4vMBIDcOvY94tjerMDR66CUwMtrcvCN+CQckAcBN1jGwcgChRGJfZs1BX0ulVgJeg/+2SFdFdbUd8fl9JsrbZCjvnudZBCg9lqHTN4JrOybC3lZTSuee6NFFc1vC9BngCMGizA2BZnuyX/k8DFXbhkStfi97CODGyKSLR+wjIW4dJGDv0bRHTxKic0zVEH/y0+TV96DJO+6/Or8LOkDJ+vWg+98whK94LpMbo8Rr7eLlZmbC3prcVV70Gk/4MDkYkRgjbadcPhFygibGRNUS8eFLtlXS5JN7/x0t3tqry5MHUKOrD7foPsgtpSUtINm3YdO83x+oXObRkoivxdGbaGqNGQ5R2xqPxfEeuZXJZ04kE62KqiVlu2fl8P+dCyjec1Zc+XsiYDyYN488xHgXaF0H15oaxPR4DuInY4JXbmrvojOUdIDg/nZAArKUeThoNL5FbmpRVktXUfHno5wey60D9TWL9p3KR46mI/3I//qB867bKoYKx2nkrhOW+vV9aQPCuQ2fFJZ93k7aU9iFSC1hytkAeSTjanvTvpWe8ur1QkxcQM8W2qOmCvvCaNowCJEGm2v/k8y+XcZQDQwEyNrtgfh22UpOaH5+YxfFRa1x+IXNpXF/Gm8KTFlKYZw6SjZ7/5Hwb9YA8VHQ0pvZrTeYyXqxGl/R0lSCf7deE2mA3OgtIwplH/p7sZIzIaKtz4EpLj3Adn854iIWdrK7ezdnjzXPdKM17MWXg2eZgq/k1vxh2wknu/fxTAK9ne3tiECKV0nUshNs31K2BdPjJb9rwVMJJpmTz1l/ZiT3H3ApT+53D1doQkBfyWmn+Xlvg3gTMYBWMW+A3ctyUs1lQX7TCVGiU1bUrMGQqh4Q8VFpftcz1nf1lOnJOOtFMcAC8cdg6MXtxyQhBK/7n/xfWwrVprghji6wfoJnYSpTHsuV0SKZnzEsWA6fyMeVEV/XNg8h+V2vmoUMYmZjyprCOZkNoIsoFO/UiBN4pIpfvwegfPOjbX5kVPT6snowcW6bN23Ci7J795+v3yi89MHpVE0vY6mm2f2duodUmhHFtOTg5Q5eUV9VV1CLDLRNOQ2MCLCSZeM6WJB9q1mmwlcEfzyl2YEvj8QKKmYIX5JSFPyAbLD7Uoxz7iODPPYf7L+ztkm7VTFi9Zu1VcmLU8Dad5sAkkk20wyw8/L4Gr3PX+gehpTILez9t/6B56Nu6CaOZc0h3pojSPTSZ3sfnO0g3K1oNiJcL41RPwchpaDb75h8JM3b3LmOPlF8p2D6vOQPk+FcMPybkqQb/HlkRmNI0IdVaqW/OrGuc2uDYG5ehxlotv/Fp29MQfPLpN90BfXuklsoSksOQZSEiFwlanCpT1BAoI1WRjeCI2vO0G2p7FubgK7LR7BUWxVwaUe/jTKL4vQYFkqhZfXWS7OA9xAkru9XxK4tioU1mEYdTIygRgRVzUwSAk+s+sDloIFt3rfdnsfPHzFt1moOPMB4qDUM5Zg4KLbBT8bebYsBIyJeuJiYBV1yI/BT3W1Qx2sYna1EtWVDptRoEgFccahfrQA2lz0EK+depVRdGThck6QJLgyhYGfxzTTCdt52ZtOuf/Gf+JTIetaDlL7USFmJ5WzMXZ84GhEftHCraGAK+cow8/DrJ9VL/Ka9iXTCeOxng/ug8i8ha1tKerzJOCI2BVHauhytuQGUDJ5VX0Nth5YL5qzsG0pK9sygCS7GZ13/2IR2/Ze+5jMxSaxJ+Qds+9corWoPlC91CQGrrG+DssB6jGiA40Ik3Rm0Rksj2WBALS/rLOKm+XYHZckfl9M4AWCKc118glGFmS4gBhlBWeUuSVY7aktTgTK+kfJaP9WrF2HSR7qqHZSQwL623Q6p1+zTCXZ/k7k8NEmxKTPUJ3VHXMW/wKajllQRDE60wyWNZym9Ilt+JDr0+Uso8krMxB9uINfMq1csDbaWCQ8kgz/bq4RVx9SSTemm4OCVWBBRMLDG5DwEHerjtxEPD86GpogWADmwZcfsI9YrQ7STjWKT3z4AhrURoHkCCtCNpqt2fFnlzQsZ81ujgp898DDCJ+lfvmiyrLqfZd2Yc+86m/a0uLZyJHv958Tw7aFvxxnR+VWWXgU7u7UKKoYs3Ubt3VsSRVBkNO78h2au9NzIxbUHpc2Nccw04IDGH18A0Mo90JYRVrHVZOOlwTqvneGdRwI6Tv6n0X5MlKsYN5JoF6FY3h+ymOeBYEikQsym9KHAdxz3gZuxk8MiGhwbyX3geuEahUddvQ8VzVac4l8BquiZhsZMnj6on1QhL6j0DX1RaLBGvX7CaIiWuCJui/FOn5mOtLetY3tItfWLu4q/PehN1KdqptEd/JNpf/X5Rnb6WicBwiIEH70UC5uRIil9f7eAyX4nDw6Z3eCdHUR9ee2HOq8ywzOzxqUgjdWv1SSlL//v6a3ABe2gU+yxtuJueIwiAAdYTQdWqPgc7HSfq1+u/KS5aJkoTqYrES1nppLeAHFi5xzakjvhEaPQ1t2abSog7cFaNA52ORySRwvvzD7lJ9VJAo1fb/ZNCqMUwazaW7SH4jylo+J5YQ5M9IrO7ZewlqGue+g9Px3qvEJdK7164JiVCV5DLGZ7x5XA2YX/21+YgdTr1nO3HnK+JQlDMHJRmPKni3H+D2VqWdwrLfP8wDCtrRxI1w4Po9efR11f92ffYL+IUYord8TTsbSo82Ehui8DF00vALq7uyuje11hGPE5N/2hGGmMsyS8BxdEOHNMKq9O4nFIk7vijTI81EcClYTSqvVLVhorQPJmHIcnz70ic3/yfpKWFbXcODUfscB9Ril7mBcWvEgwgdmp2TTjwzb2orm1IyEgRP6kabM1I9CFlFKBCQXjTj1dYuytTPuLNH75vbtOo+A+6XMKMdJLJ3+Jd+Nc0cvtzI02OZP0SvqxVwP86rG4AHKD1veru9J8h4JrnzdhdIJjr7cXpjTkEG4WSjEXiiEPt/W0uZOaujz59ySU36Q78/H/FRfXWLDhVGxPZxkyjOK5fds7ivbyxJiEQPBV4mAVbfUSSqRQyRS+bS8e/TwX8qTxbVGHzBoMkrULEPWVZ8VKFgtFOamopl5SBLJugi+2OcdAi8ye+TIuyAzJdSydPO2p1vX/SaFNZYmOdn9aeJO6rFSZ+mRdl6iZ0d5caeOg3pnvVs6Ypqjd8H/QHeCyg+NwMbBOxzX+c8m+McE5kMm7TRT0qgJKYoeFaJJmLFiFC1jt/Hllv6ivfD8H41UU6l/Q0Ea+wFbozw4VCpYPvlb9Flh8Ao7jWVrD8/IPXcgVtV2cFj3BlrjL0hM3w7oDRRB7RLf5mB2DKPXAXno9L5X/6XPpO0DzpRjBFFQqRUP8GsHez0RaoK1vtEnqFZxs/HRSrh5snizmd0Mzzv5iaFlaQ5sg4IWQtyGdCy4QwryOLfV+wwpnFLMfnrFc/rw8PvS0Wpv9dCHZ73KuyLjFqf9vFILA6FLO9ujDZNfQR+Gc4vrzQKb/wxcgcK8s0ikz1rahWBRyHCAVDSnS3g6zD3R/QRj8upQOXR6JN0EZbpj2qJiPpWL2myBtuc4D5PNHwj3C2mInT6F9KEfrVoA6hzAuZS0btNGYw8wS+yglRq2LfduaMYTAD7ChXb0aexggZfUVlkRvfPsz3P/6cH9XOi88au7tvZdIgpQDmnZNv8GFMu5A9/j5aFDwLqaLqsizTiU3pm8JT/u1Hvk/Mo7cjOjAhJbxsMTiE0CTc2jqusdhnr0OkwihKY1RkJi8krXXActrLSV8lJ6eiVI75kWKoIZAVBc0Hb3nnTvIeNSi3N/Q2HvS053Az0PNQ+pdiIvieFFB/1vmWVN8QUL/X6Lc2MakncTjc9kVi82zZ8xq3VpHslyt06m1049Y6qMoOCfK6dJLI7rNQfAPpkNb86GAj2Njmdo/mniF87bTdFFArhZnFVMvcR1d4VibeP8VT63jPmPNfS4JqNDNiE4mKdCnxhpjqFesmrD4b5yFwOmzZezUv6MnsLbNZM8By736WhU8+oGKIwlVMuH2raOeSos4yPpkqXergM/bYZy+k8TSLQJuQuSQ6dufYSDwLdaJCxAKMVt4tjT7sb/mOAwa67Kv+yKnBm1NNOVJjpK3yugfW/HuxOouMKNHHukOWqQ5B5gJyxqPDU97eubng5f+Hch7nR5lKH+BEq3LOHMDXjxRprh/V0Gf68B255gt3qfIDlfd/Nkfz8hmD+rrjE4U7QnxRd61GN3rAOLLzMzC/4qWNc0BUYmPraen7pB9qIrRPXYeMH1un1c+yk6bw9w6O/JBhKJ8ZlepqVcwBowwMjzEu/GNujTgTSZjZ4aXYcbArMnxPnxha6TlMLOQFT6Wbb0cVIYhaExOa+V2l3xBVfjqpVpbkp//2CxwllW9nKUMDffSkeKb9yTtuAfgRJ4ZOXNGXSFz7ponk84EKKoHa9RyEoWZJY3f38c1PH75TifO2bpLeLrr5Wxa29oCCNJjCxn/WG6dbsq0lS6J+MO4iqpVmrRHDwWUWqqDfMI1NXLNgUngs3IhgPkwiUEXkzcOnEtkl8tk28qoAc16ysa32gQ/qNCuTsUCu/FJIzUZd1sHoX+CWnMcVht699taIJJUpwXZ1TDDNIzNmInDED6SvbyTVJ3em15r0Kwse1+T+3B8snJZLIbX2c3o+i8uqMKBbJ2eaos2rVs8W3OIQmQordwJEkQDLztqieINVIHToiQ5F5c3wN0HS14MZnSuXF5j+4tAQ4aVF5hzx/VDwY7tilUbJKI1e9nn8iut3bdFKSdUtj6ImYwXNIZrnR7ycZ8cCH6HlrCD7tRnrfr6T9y46vY5kiVuaNUssU6XOSGiN+A+J0bjF+xO+CIuKoSZ4S2nAfCTzlaY9ovWGQNPlr5pm3tCp/MGjE9EtPsfhRRryK4mfqPhnzJbJ26KH8uhoFXMq7X+acMno9h9kU5J7f7/e/5WAfCzIxPPIxyqXEOCnw4erolF6XvIC/Ds292OiSw3cxP+yAoG/3bh84CJnyn2kCE3u9g1KCqLYBDQXWyBwzv38/gT6CnDmh/zhq8xOX2LtraHFCNsP98GmzDTdpelj7biamZEOvnRfJ2YFvW2Xq11Y1v/6awd4Gb0/HxrjmRS8oZIeu0x9XrDj/igI/QPMxjoCLEDlg21/zxz/eD1z/jXn/zz6IANv8F+r/8K1GPy/q/+/zcsNHZWs1QvAb0G1gl9twIsOKSGQ7ACQT6LBAMwMCduUHn+fvTzjRf+cP+BnHHBzkjEtqKMAHFxxMfBJoMh6RZES/pHwqMdfZ0FgokR6hlOO3hWBYGMgImvEhQWik08biajaSBcvfvEHo6YLEzBzRHDSscMVVrvIFF/dHwKxCHUHYH7Iv+mhBtgIVwgFJxUA0OT6wQriO2uFYNlvhQrQZUWiVmlFlkAN2O6oAFhNV6VCk3q1JmkxWbBMNepMMaRVaJOrZbRpV28rqKATQksslt2e1sFtYkcwonAI24DfEIUNH8X/6g4o6l5t9hZZ7NLEsuoOGraCecPcOixQ70Qn3gn8HMB/w8JoFUTsoNLaVsFl1dp2bJoQEzNqotYKPm3XoGaDamDqoEC1ECi4N/4BGQAAAA==); }
-      @font-face { font-family: Comic Shanns; src: url(data:font/woff2;base64,d09GMgABAAAAABD4AAsAAAAAHyQAABCsAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgRQRCAqjSJ1QCzYAATYCJAM4BCAFlRgHIBs1GzOjwsYBAFEeR/ZfJnBjCNSH9khnUltfq6qH7TT8FMexVTWjh7o+p4gz8uPaBoz4cwyp4gqqlTjfHSHJ7E+07Xszs7vEJiII30UiVcQsohQLC39VXbR60XrR5UWU5/2I9tDNxLNMVxHdkFDD6yN4ailW+WX8ACAi7tnv3TSTNQkFlkESWJpAEmrz1f+7/V/Tza52r1oOnUlsYj8floCm8K7/N5f9sTM2QCVAfZBkD+H5EybRtZgC4kIZBk649j9Aenj/a620Mwm7tFthQu4ibISKUwtvf7pn7m/XbMKTf0SdPiDFUD7oUJGLBAKPVD7KRHiRYeyiB2hi6trNGCs4rnuIq6IIxbAfL54BSF3oFjTAn/YASBxcGD0BusDRtoDg3xc/FfhZrO2RMZ9RN7cEAPpbqb9ex5bsEIfEpyPQVFG2vB2ZhOBYRDRr02Gm2eZaYIkVVlm70RJh68qpapFlwZp/g+1dE2NDFWUlBXk5sSjkSNAwCcCYSVhyRQtg7gCKBwDVq99mdBzg8eeH4GkaN/mJr5NmWeRSfYNbV6yPlmaV8UW2eDxTV5TZkkzmxouqbNd3gSm77t9nMOGsmhf+TphSh7S1iCm9HDWcL/zkEKEaJXjzRE/KE9HB0kqBDNKpBjwuL2d2S/UpsAgVCQcy9GKiPbH1RgdluVBWNbVy6/SnmLjw+qQoxXHO3Zja/5YP6HkIZjDh8hBCkVIQZL+XUeF5XjepByzUJUUixPeK8Qa1qdteugSQzDpFKRuowM/Ly9ARZ8x5fIjQ3SI0EITZI0sK4qynbQXaZW6oy6JEj4sE+uzxeY6JJsaJBkAP2GrkJ52lJ3EJaNtfVtS2R57PeQccQDP7oK/qqZXz8+217o8DGp76A9FU344BQG4SFsfjCJf2tt66dqB9OpllLwlf3x8jHIpyd3wVXULYWdEm7i2XAsmk0ibcaQvTyc4CwGNbwh4ZYDfHxP/Glh8FCmpZtLuqMlSf0qR4zI/4eu7Ywb7B6OIu4f3YuokiZT74IkxfPACru47GbDMhrfbGCF300V0k4LzKhGUJYAM0BBmxx7gAXvq/ezETaGLtcmNwywGh4Zb2/spqo594CdNOmCYCgG4Xd8uYcEZFjTI0CMsBmghflA4xsRX7oWCxIz/NzOoZZ1RvenFe3EZ4fJeE6FlUMMu6CzOaJ+NPBIZSCjk2GLi8PT+vIlIITexH9eo5JnysXQLUrQj/bFZOMeHUTRGWDAQucxmJ6LK3d0aqqsbU4LDttUX7eFcjY1PxprnSB9oJr1j6XIgcXesCSeSLvgDMo1bc5c93pagpf16Wu4RFSA+bVYpTruELbNrYo2an0suYcPEivGIJAD1YTSsRJpPr2LIZ+SEmo7JHNEJfiJTiya6fJ3w+bXeZu3Cpa/PqH8AbTKk+YktFg2FKhmOa663qj6JTanRb7ER6ptj9B0OenK71r1vQjAZST6+s5gw1Fu8QptxTPDcIOGZAkAsFU9i9///VN68QYsIFgxA+Y/4aE7UBIK/1UU/LclYSvdpi+FQ6IQr8naX0vtCYniTlXqzAMiHn6PbDTuAkTomwyhWV2HqCJ+6YX1vawkQzP4Xkxa4rJsNABgdh0FZOzPEhQO63KURvFhYupgGADEwHJatdaX+LQ/VX/Eh5spJuZwmfX+c0EKaXr3j5VxThR5AMDsLqpdQXeCzVZ9DJRaoAkOXkpjxit7oVJX9wNXwvlhbfPnkauCdPKKQ8UZ+K/STDsodQwXg1T3hXbl0H1omh+gBE75mo/SyPsO4OHsOfZ7sm9d7r811MTE0pKENZjktQ9V2EBsgyHX1/hZ91Xl89CIelap8W/omAD9Cx2HHOnmev+le6I0suRiL6RuQ0tq4lNWnjs3TI8mrBh0Hrv///ttLCmWMaiBLp7bOdoUxVD/LNQorCJL0r959Dap5UKt53uwcB/IN3CRf0xqKjiqb8X1rH+WlTeqxK+T5GFntJ1RoYomlG80HvTDrg18rJgldrHa0wY7WJlnUiAfVrmsHyOY9Mpya1kvZlI5y4cH46IX3fTfG2DbbSP1J4Yk3eNCpFRYlk2M2J+41iKz2ZmUybxXhWvqe/ezoZx4y8oNLPG+TEZ+/TEwiLE36XMJFuezU3lb5K32cYUPoXKW+hUyQ6sSwdaBrkAQmhgl9lLTunuVC1Rj2fa194a7lLwJi/2LVNu0Nzm9Q3xa3eyMQSXBff8HpdV9QhYsy/VlfFPsi9wt0XqefU7uSeaUpVv+L+DvU65f3M0yi6RreDipVz87jut+CU/vm4uzj89x/5FKlhHpab5q9sSTjDcrcjWWJRkmyiZBrm7PFFh5oEb0vB2OI8/RyqlWfo7LJEuKOoJNh05AWH2aKjERtauQTQL56VdhyoYzoU6efOpyEMf7yuJYR0ovl4I8eaBLVFSLP2qJSx3g/tr/Z/r8hPGh+wNoollvE1oQ6Xd6UmTJ3gUUxbZTD8dI2tLuxkFhltX197Aeq2CjTx72F4hL9Tnh3IlH8scVj0X97Wbgoz2kSZSee2NYTKZ9iC6sLpzm2uv7JcVobm+0o+yzd/c3DIaP/hwSBOudzaoKXcm0rUTLOURaaVwd47NtQ7HSoly/W8NkYpXf2lhLH4y9lNWRPNsxqqy7YEnb8ZwpYJ3nXx+BTTrKjTdl7f18DpDXeVDa60k56efJ9ZW/yNuRnO0UpSN4qHoUabyxc1bDPc9B1Gwq/7rXXQ4x2XB2PRIGtefgwjad++LD0EaxO9kYzC4QZb5uev5v12CyaOv0d1DFehrqXOcJGl1TKw/uIB4MvrWKHn2TP9RDnVcd91Po/2xDOJLTkKpQiGxLdJhvE9fXTS+/apCrb/zCaHQuhflJaIK3JpejhmO/vyip0QaMtdE2+e6Coqbm6Ey1m2JSNTGN3Ax/m5hypdTdbqoEasowgh3o9/SySsw764fgs04rVG+27p2BuzMkUrqcV4C96UrVKEV4X2yabNb9Rv1BsUSgkkQfIZFG6EX+BMta28UIPhn/L+oVfHU9QEKA4W+hf7S6x1wZStSFd0bNN13uvPlcyYErMkTLGMNfMOFRJiiM5Ka0+bkEYR4bHf2wgtftWqfSB1f27fu5GMkMkyfhQOPx3Kj4MWXnxQsKEZi8mS2nH5PZGKlOyzPvjLOdl19cgHd2fGl4xVRWUNXR21V0+A5PplEPPOjNVNkouKH8+cy+Q42tJ3BLUUNUXz8B/ZvKjT2kJ1PhPGFo92jJ2eABNbzC5/mywivB5dh2/AbRan/r4bBI1Ll4+Gn6dp9hhzlT6Zoi1kJl4KM0SvQ4MNJkF5LIZ4+bp7RWH9fWZ+EiyDJZClN6QJG26E555kREVea1Ft0D8VJVGCDfAdHvnJrySEpYOsuYpfkk+axtrM+qmfbVUoOSPvVTcbs87v0yA8vEMtrsOMoSzENLKCfEHCSPPHE3oarhiGG7KLwl995qVIhTylItrpKc9uMlUGT71ZJYjMwpaa5VjTQkjZ/S/gBlad+iW3sqJiNuli6MD4xZD8f9GR74d7augCog/obbmRDDlzLrQRYn/l9YJQLHeY50zJ/6IQVvKZGZ9/KR37gTORh9DL3df5mpK9akigBLSVyxjM/u96d/irxjC0RnxI1lrjlp3w7k0m/paPrzz+10vTD44sNCCSXlM0+aMCinvsT7NVoAhG0lOekN03WoMww3CcV5VkMTLuHRIxPrZFQwOY1leEFQlWYLSaL96Q1RCrrefUrrY9D3OqbV1PPnGNR9uikmxpkqHqu2YpkezxxB9MPa76545OmiK8XO9cpmB3XqhKXDXXuK9duJTGvnbb78yHr7fob9nzoYGh43n+SO74jKLiiXnwvOILbZ+BYcJoZidqUxly0yqKfMb9grjPqOe/ozJYtb2c4zTSalkjKxRu8Za5RGvcL3K7DfpZ8D4mEVmhVAjKDN37NKWb/tFXPy8uJJTw5DfQwFSmtsyJB9Z2vp3VNlVgY717lqtVD6YezhwXul8OeLsjAxmJ3vJ+lWra0NIKVkjeL4dyxlWvg3upfxNdre6PNtFzGQkBfHlXPaaEjwdSX5/ImdoYWXhaSj/4uaf7yVPGnO/razq67LiA4u54vI2i+XdeCCZfBc0dLY0PeYRrny7EKB3gBtf4B8KbLmx2T2W41z+frFOwC0ZrV71SMX/cJ5kN0wTWtXXPDla1rethQ1vicUsop7thwNT0gas/bfnQg+UcD3P9vTYNLdRyYzL/k9hBi57ltDpeNGhfWDpoliTR+6CVopuCgoCaybiVhl8E/lyGND5rtMDcmIwHBHEv6QZGIJ0BI9XXj579+Wz0RKbY4dzhnO+t5J2pgPvlb38udEDe0uPu7d1ytrsIP8K/P3Ime8V3cutS3wptJHtyWNVwbSGKHPmIOZZ9Go4jGcnfAjuW471byc7lcoeEdyBHM6Jie7I3B8SPA9lXAl3bn79xz8rtzp/ddjS/4S7mNz70Z53K77zHL1WhfwR2NMfzFQQAALK/c14mizWnlSzZBwD+UsVfAAD/l9XZ0f/f9OHTLQCUMAAABP68l3EPWrNtGmGOPh/OKe26AOAzcJLly5PDLy6kSkSDgBJhFeK6hFUq4eMV2H/6MW6l3U/BABAEwA8AT++nMA6BTioA1dtnt+sRj8H1mODy/+vfzebcj/T6T5SPv8zne4EQPRNr6RuXS1TTHS85GWGr3qk3BXqJF3G46R1oN54JY0DNh+XWgDJda1ArwmbYPkK7mzMzKCfNVpzFPHbS3kGoeMvrMySei6EIpQRyh7eGWGhLQULHezdKVbsTz6FECRVPyrPnzzg5fx06tdOOAmtcTKLCG2AbzZLpbEhNGxp2Y2FDLoSRDdTZCem9VBZPHeBxjmMdktPT2lgdSnhmrI6Idbgn4DenjokEPGYEJz9RdpXdBJAx7RjG1ogUUhxbgHyU8hVkI7hQ0xJSJRcvC+WkxiJcGBMJR4849hSSBGX7kqO9DosYbLAajyQ5R4njRq1NXGIGkFzEA3Wk9HJcmy6pIPcQCEa0CZRMuPBwJwmhiR9oIM8Qbc0AKCCpdTpibQsmKZQTccfwjxc2viNMRIkQk/3GStyGZwgk7v25jlP+mpgyEvmPkKeJ2eSgrNXRmDpNql5wI9zIUM7JInlLrDaeTm6bQZDhJjKkfYIAJVGa70Yt/ewHpg65ydBeFM51JNg+D6Kx+tTBSeKJBgcudKECjWNQCOaE+CPRuL7sqiA1TMy328WsqpULLZtjBXt8+Be51unEBVDEBpeA+WhcuKCVJkBPwZkkVA7fqdqZZEIcKaNtek7aunaZ4kSqCAO/ZfRH8YynoCKlbDyP+SqsZpYpTnsh2xkiVdaVhXKnM/JQ9oBlGGMRL5DIfJngHV7wEugUHWEnqSKyOAfZwolf7LjtmAArJbJyyWIJOIiyY6WAugmJeCamqVIJL1Zz04Rn2BkK7KqKcJvIjCwsoUdAhQLnubV4Dw3hOl90KEus3PKkLPNXC7oOxuIQtXWdlANr7KYR/oCtVhQVxYjZte2sM9FCcQrv0TKZFiLNooOUVc1iu6CUxXtakXaJOSUyk/YjviswZlj1FOfEAc80aJxtAtuUztDaLHPOnGmwQzsBcqi1esJWfQz0yQR5G8JlGKbjngkHzGWF3KJganyiUGgp+Go4xgZ6SVAfemJSvGaYhI7BcLhGTHYpahycGHri9fcj); }</style></defs><rect x="0" y="0" width="1452.6284042512102" height="785.1072998046875" fill="#ffffff"></rect><g stroke-linecap="round" transform="translate(68.21875 285.1854248046875) rotate(0 57.140625 41.75)"><path d="M20.88 0 C40.07 -3.44, 67.81 3.23, 93.41 0 C108.58 -1.7, 113.64 4.43, 114.28 20.88 C110.37 31.89, 114.48 43.19, 114.28 62.63 C111.97 77.06, 110.19 79.94, 93.41 83.5 C76.29 85.88, 58.8 83.04, 20.88 83.5 C5.01 86.19, 3.57 75.81, 0 62.63 C2.8 49.69, 3.12 33.02, 0 20.88 C0.67 5.24, 5.02 3.06, 20.88 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M20.88 0 C38.48 1.33, 55.66 1.28, 93.41 0 M20.88 0 C44.6 -0.2, 69.08 0.17, 93.41 0 M93.41 0 C108.93 -0.66, 114.81 6.61, 114.28 20.88 M93.41 0 C108.53 1.09, 112.71 7.42, 114.28 20.88 M114.28 20.88 C112.83 36.64, 115.76 49.99, 114.28 62.63 M114.28 20.88 C113.33 33.37, 113.92 45.86, 114.28 62.63 M114.28 62.63 C115.09 77.36, 107.86 81.53, 93.41 83.5 M114.28 62.63 C116.05 77.36, 107.29 85.79, 93.41 83.5 M93.41 83.5 C67.37 84.88, 43.52 83.69, 20.88 83.5 M93.41 83.5 C64.39 82.39, 36.31 83.79, 20.88 83.5 M20.88 83.5 C7.14 83.77, 0.22 76.33, 0 62.63 M20.88 83.5 C7.36 81.6, 0.6 75.33, 0 62.63 M0 62.63 C-1.85 48.15, 1.08 32.11, 0 20.88 M0 62.63 C0.19 51.66, -0.9 39.69, 0 20.88 M0 20.88 C1.08 6.53, 5.03 -0.9, 20.88 0 M0 20.88 C0.95 6.51, 4.8 2.2, 20.88 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(85.1171875 271.7322998046875) rotate(0 57.140625 41.75)"><path d="M20.88 0 C36.65 0.88, 53.33 -3.33, 93.41 0 C106.92 -1.99, 112.95 8.68, 114.28 20.88 C113.65 31.24, 112.8 40.44, 114.28 62.63 C112.86 74.18, 104.02 84.03, 93.41 83.5 C75.64 78.75, 55.15 82.05, 20.88 83.5 C6.55 81.54, 0.98 74.7, 0 62.63 C-1.9 48.94, -3.45 40.75, 0 20.88 C2.95 9.1, 6.34 -1.4, 20.88 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M20.88 0 C44.26 1.44, 63.6 0.29, 93.41 0 M20.88 0 C40.78 -0.21, 59.6 0.09, 93.41 0 M93.41 0 C105.83 0.69, 115.59 5.93, 114.28 20.88 M93.41 0 C107.36 -0.58, 116.13 6.78, 114.28 20.88 M114.28 20.88 C115.72 29.87, 113.43 41.74, 114.28 62.63 M114.28 20.88 C115.3 30.82, 114.91 42.41, 114.28 62.63 M114.28 62.63 C112.36 76.73, 105.74 83.18, 93.41 83.5 M114.28 62.63 C112.48 74.85, 108.46 83.79, 93.41 83.5 M93.41 83.5 C67.59 85.09, 44.24 83.88, 20.88 83.5 M93.41 83.5 C77.17 82.58, 58.4 83.6, 20.88 83.5 M20.88 83.5 C8.45 84.11, 0.55 76.75, 0 62.63 M20.88 83.5 C7.06 81.8, 0.99 74.25, 0 62.63 M0 62.63 C-1.18 51.77, 0.62 41.51, 0 20.88 M0 62.63 C0.34 46.95, -0.32 30.63, 0 20.88 M0 20.88 C-0.1 6.15, 6.07 -1.37, 20.88 0 M0 20.88 C0 7.01, 8.25 -0.1, 20.88 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(290.1015625 640.1072998046875) rotate(0 186.5 67.5)"><path d="M32 0 C140.02 -4.99, 249.26 -6.46, 341 0 C361.27 3.21, 371.54 8.64, 373 32 C374.4 45.04, 373.03 60.55, 373 103 C370.4 126.18, 365.21 132.91, 341 135 C225.99 138.51, 106.01 138.75, 32 135 C11.12 135.2, 3.06 121.49, 0 103 C2.24 85.97, -1.84 69.24, 0 32 C-0.72 14.27, 9.6 1.86, 32 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M32 0 C147.2 2.31, 263.84 0.13, 341 0 M32 0 C152.79 -1.4, 273.68 -0.26, 341 0 M341 0 C363.24 1.89, 371.63 8.68, 373 32 M341 0 C361.89 1.32, 374.96 8.55, 373 32 M373 32 C373.51 49.51, 371.4 69.4, 373 103 M373 32 C371.89 53.55, 372.75 74.94, 373 103 M373 103 C372.91 124.05, 363.84 135.32, 341 135 M373 103 C371.37 125.1, 364.41 133.43, 341 135 M341 135 C243.35 136, 143.9 136.22, 32 135 M341 135 C252.05 134.58, 161.61 134.64, 32 135 M32 135 C9.49 136.67, -1.21 123.37, 0 103 M32 135 C12 134.37, -0.77 125.37, 0 103 M0 103 C0.14 78.38, -1.66 53.05, 0 32 M0 103 C-1 85.17, -0.34 65.21, 0 32 M0 32 C0.75 11.29, 10.4 -0.03, 32 0 M0 32 C-2.27 12.93, 10.36 -0.31, 32 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(304.0703124999999 627.2908935546875) rotate(0 186.5 67.5)"><path d="M32 0 C99.75 -0.07, 161.54 3.63, 341 0 C363.88 -2.2, 374.83 7.14, 373 32 C369.67 56.51, 369.73 80.69, 373 103 C371.86 121.04, 365.88 135.99, 341 135 C256.53 132.69, 168.68 133, 32 135 C10.03 134.3, -0.87 127.4, 0 103 C1.64 86.22, 3 67.78, 0 32 C1.84 9.2, 14.11 0.61, 32 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M32 0 C115.52 1.4, 198.1 0.3, 341 0 M32 0 C146.69 2.05, 260.35 1.75, 341 0 M341 0 C364.02 1.02, 374.31 9.03, 373 32 M341 0 C363.28 1.65, 374.07 10.28, 373 32 M373 32 C373.05 49.43, 374.13 67.61, 373 103 M373 32 C373.56 53.48, 373.1 74.79, 373 103 M373 103 C371.81 123.87, 362.02 136.69, 341 135 M373 103 C371.99 126.23, 362.36 135.56, 341 135 M341 135 C247.91 132.51, 156.62 132.69, 32 135 M341 135 C261.96 134.72, 182.4 134.98, 32 135 M32 135 C11.59 136.42, 0.19 124.28, 0 103 M32 135 C8.96 137.09, -1.24 125.29, 0 103 M0 103 C0.44 84.06, -1.82 68.4, 0 32 M0 103 C1.27 79.48, 0.98 56.36, 0 32 M0 32 C0.16 12.48, 10.16 0.85, 32 0 M0 32 C-0.57 10.58, 9.84 0.71, 32 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(477.3994140625 378.0802001953125) rotate(0 110.28125 47.6328125)"><path d="M23.82 0 C71.25 1.44, 121.04 -1.23, 196.75 0 C215.34 2.43, 217.56 10.86, 220.56 23.82 C220.43 39.4, 220.37 62.4, 220.56 71.45 C220.84 86.46, 210.56 97.66, 196.75 95.27 C137.78 100.62, 81.78 96.46, 23.82 95.27 C10.36 97.47, -2.73 87.07, 0 71.45 C-2.96 52.81, 0.19 35.84, 0 23.82 C0.08 10.72, 6.94 1.73, 23.82 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M23.82 0 C67.79 -0.23, 115.28 2.19, 196.75 0 M23.82 0 C72.95 0.25, 121.65 -0.72, 196.75 0 M196.75 0 C211.99 -0.05, 222.44 6.28, 220.56 23.82 M196.75 0 C213.5 0.36, 222.09 8.09, 220.56 23.82 M220.56 23.82 C221.31 37.36, 220.25 56.1, 220.56 71.45 M220.56 23.82 C219.9 38.62, 220.14 51.22, 220.56 71.45 M220.56 71.45 C219.03 87.42, 210.82 93.29, 196.75 95.27 M220.56 71.45 C219.84 88.77, 212.6 93.46, 196.75 95.27 M196.75 95.27 C140.64 96.38, 87.94 95, 23.82 95.27 M196.75 95.27 C160.68 94.58, 125.89 94.95, 23.82 95.27 M23.82 95.27 C8.02 95.61, -0.4 87.6, 0 71.45 M23.82 95.27 C6.83 96.97, 0.75 88.96, 0 71.45 M0 71.45 C0.08 56.74, -0.66 41.56, 0 23.82 M0 71.45 C-0.02 54.9, -0.79 39.32, 0 23.82 M0 23.82 C-1.09 9.87, 7.36 -1.79, 23.82 0 M0 23.82 C-0.48 8.17, 9.74 0.58, 23.82 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g transform="translate(511.02071380615234 400.7130126953125) rotate(0 76.65995025634766 25)"><text x="76.65995025634766" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Endpoint Picker</text><text x="76.65995025634766" y="42.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Service</text></g><g stroke-linecap="round" transform="translate(102.2177734375 257.9141845703125) rotate(0 57.140625 41.75)"><path d="M20.88 0 C46.28 -0.94, 80.79 0.72, 93.41 0 C104.19 2.4, 117.1 10.26, 114.28 20.88 C117.53 35.09, 113.39 42.67, 114.28 62.63 C113.78 79.14, 109.16 85.65, 93.41 83.5 C76.92 81.02, 54.36 82.46, 20.88 83.5 C4.7 83.19, 3 78.05, 0 62.63 C1.68 42.54, -0.05 30.88, 0 20.88 C-3.48 6.36, 5.12 0.21, 20.88 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M20.88 0 C46.71 1.43, 72.02 0.45, 93.41 0 M20.88 0 C39.7 -0.76, 56.01 0.02, 93.41 0 M93.41 0 C107.38 -0.04, 112.83 5.4, 114.28 20.88 M93.41 0 C105.18 -1.7, 112.43 9.16, 114.28 20.88 M114.28 20.88 C114.06 31.68, 115.46 44.3, 114.28 62.63 M114.28 20.88 C114.08 36.13, 114.93 52.01, 114.28 62.63 M114.28 62.63 C114.53 77.24, 106.51 82.14, 93.41 83.5 M114.28 62.63 C113.73 75.85, 107.43 85.02, 93.41 83.5 M93.41 83.5 C73.07 83.17, 56.48 82.82, 20.88 83.5 M93.41 83.5 C73.98 83.5, 55.11 83.83, 20.88 83.5 M20.88 83.5 C8.61 83.03, 0.17 77.43, 0 62.63 M20.88 83.5 C7.32 83.09, -1.65 74.76, 0 62.63 M0 62.63 C1.3 47.78, -0.48 30.94, 0 20.88 M0 62.63 C-0.89 52.85, -0.46 41.69, 0 20.88 M0 20.88 C-1.45 5.25, 8.55 1.64, 20.88 0 M0 20.88 C0.61 4.94, 6.82 -1.54, 20.88 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(128.9084243774414 274.6641845703125) rotate(0 30.449974060058594 25)"><text x="30.449974060058594" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Model</text><text x="30.449974060058594" y="42.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Server</text></g><g stroke-linecap="round" transform="translate(470.3876953125 140.3614501953125) rotate(0 110.28125 47.6328125)"><path d="M23.82 0 C69.04 -0.44, 115.41 -2.92, 196.75 0 C211.63 1.35, 222.48 11.39, 220.56 23.82 C220.18 31.29, 219.35 45.04, 220.56 71.45 C222.5 85.21, 210.82 94.98, 196.75 95.27 C148.05 99.11, 107.88 97.98, 23.82 95.27 C8.15 91.93, -0.33 86.03, 0 71.45 C-0.17 62.04, 1.9 51.19, 0 23.82 C-1.35 11.01, 11.48 -1.99, 23.82 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M23.82 0 C80.54 1.26, 135.33 -1.37, 196.75 0 M23.82 0 C83.27 0.83, 144.24 0.1, 196.75 0 M196.75 0 C212.38 -1.16, 222.02 7.56, 220.56 23.82 M196.75 0 C210.97 -0.21, 218.68 7.7, 220.56 23.82 M220.56 23.82 C220.3 39.34, 220.95 54.89, 220.56 71.45 M220.56 23.82 C221.75 40.07, 221.52 55.58, 220.56 71.45 M220.56 71.45 C219.87 87.55, 213.15 94.55, 196.75 95.27 M220.56 71.45 C220.64 87.7, 212.04 93.53, 196.75 95.27 M196.75 95.27 C150.02 97.34, 100.19 98.1, 23.82 95.27 M196.75 95.27 C159.18 95.87, 122.12 97.55, 23.82 95.27 M23.82 95.27 C7.17 96.38, 0 86.34, 0 71.45 M23.82 95.27 C9.37 95.14, -1.77 87.34, 0 71.45 M0 71.45 C1.78 54.35, -0.91 36.58, 0 23.82 M0 71.45 C0.11 52.85, -0.74 36.39, 0 23.82 M0 23.82 C1.23 8.88, 8.75 -0.46, 23.82 0 M0 23.82 C-2.1 6.39, 6.03 -2.19, 23.82 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(481.6190081834793 175.4942626953125) rotate(0 99.04993712902069 12.5)"><text x="99.04993712902069" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">L7 Proxy / Gateway</text></g><g stroke-linecap="round"><g transform="translate(583.2613405725397 240.8028564453125) rotate(0 -0.07611351315927095 68.138671875)"><path d="M-1.19 0.76 C-0.89 23.54, 0.52 113.85, 0.88 136.59" stroke="#2f9e44" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(583.2613405725397 240.8028564453125) rotate(0 -0.07611351315927095 68.138671875)"><path d="M-8.04 113.23 C-4.77 120.29, -3.52 125.69, 0.88 136.59" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g><g transform="translate(583.2613405725397 240.8028564453125) rotate(0 -0.07611351315927095 68.138671875)"><path d="M9.06 112.97 C8.49 119.91, 5.9 125.37, 0.88 136.59" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g stroke-linecap="round" transform="translate(750.6435546874999 614.4747314453125) rotate(0 192.08007812500006 67.5)"><path d="M32 0 C158.04 4.59, 289.17 2.11, 352.16 0 C374.5 2.14, 385.78 14.17, 384.16 32 C380.34 58.45, 384.72 90.14, 384.16 103 C384.95 121.39, 372.03 134.63, 352.16 135 C283.11 135.67, 217.71 136.84, 32 135 C10.4 134.18, -0.97 122.58, 0 103 C-2.31 73.54, 2.48 47.77, 0 32 C-0.77 8.01, 9.96 -0.29, 32 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M32 0 C125.72 -0.2, 220.61 0.88, 352.16 0 M32 0 C100.58 -2.23, 168.62 -2.12, 352.16 0 M352.16 0 C371.8 -0.78, 382.64 12.44, 384.16 32 M352.16 0 C373.2 1.21, 384.15 9.66, 384.16 32 M384.16 32 C383.15 60.37, 385.37 87.56, 384.16 103 M384.16 32 C384.71 58, 384.05 83.35, 384.16 103 M384.16 103 C384.41 125.28, 373.49 136.81, 352.16 135 M384.16 103 C385.42 122.08, 373.35 135.39, 352.16 135 M352.16 135 C252.85 132.7, 152.26 134.2, 32 135 M352.16 135 C277.01 137.27, 202.72 136.84, 32 135 M32 135 C9.75 134.61, 0.37 123.55, 0 103 M32 135 C10.58 134.83, 0.13 123.49, 0 103 M0 103 C-0.39 76.36, -0.28 46.02, 0 32 M0 103 C0.19 85.91, -1.05 68.06, 0 32 M0 32 C1.64 10.1, 11.49 -1.64, 32 0 M0 32 C-0.34 12.02, 8.7 -1.11, 32 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g transform="translate(755.6435546874999 631.9747314453125) rotate(0 186.12994003295904 50)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">            InferencePool API</text><text x="0" y="42.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> Selects</text><text x="0" y="67.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> - the model servers (the endpoints)</text><text x="0" y="92.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> - the endpoint picker service</text></g><g stroke-linecap="round"><g transform="translate(462.5791015625 411.3730470828506) rotate(0 -121.759765625 -28.974548443769038)"><path d="M-0.98 0.09 C-24.45 -1.96, -100.69 -2.6, -141.04 -12.31 C-181.39 -22.03, -225.85 -50.73, -243.06 -58.21" stroke="#2f9e44" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(462.5791015625 411.3730470828506) rotate(0 -121.759765625 -28.974548443769038)"><path d="M-218.27 -55.02 C-225.22 -56.43, -232.35 -56.29, -243.06 -58.21" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g><g transform="translate(462.5791015625 411.3730470828506) rotate(0 -121.759765625 -28.974548443769038)"><path d="M-226.12 -39.83 C-230.82 -45.53, -235.69 -49.74, -243.06 -58.21" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(273.1737523901456 341.5802001953125) rotate(0 68.55846812991925 25)"><text x="68.55846812991923" y="17.5" font-family="Comic Shanns, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Model Server</text><text x="68.55846812991923" y="42.5" font-family="Comic Shanns, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Protocol</text></g><g stroke-linecap="round"><g transform="translate(443.85546875 188.5137939453125) rotate(0 -112.228515625 29.22265625)"><path d="M-0.68 -1.1 C-20.79 -0.89, -83.63 -8.3, -120.94 1.71 C-158.25 11.72, -207.44 49.33, -224.56 58.94 M1.16 0.93 C-18.54 1.29, -80.92 -6.18, -118.67 3.14 C-156.43 12.46, -208 47.83, -225.37 56.86" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(443.85546875 188.5137939453125) rotate(0 -112.228515625 29.22265625)"><path d="M-209.44 37.6 C-215.6 41.42, -218.51 47.98, -225.37 56.86 M-209.44 37.6 C-215.11 44.17, -220.1 49.91, -225.37 56.86" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(443.85546875 188.5137939453125) rotate(0 -112.228515625 29.22265625)"><path d="M-200.78 52.35 C-209.39 52.05, -214.69 54.54, -225.37 56.86 M-200.78 52.35 C-209.52 53.95, -217.46 54.65, -225.37 56.86" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(275.7103710609954 149.0489501953125) rotate(0 51.191972689004615 12.5)"><text x="51.19197268900463" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Traffic</text></g><g transform="translate(468.03412875362244 286.8809814453125) rotate(0 55.69806259269109 25)"><text x="55.698062592691095" y="17.5" font-family="Comic Shanns, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Extension</text><text x="55.698062592691095" y="42.5" font-family="Comic Shanns, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Protocol</text></g><g stroke-linecap="round" transform="translate(822.63671875 380.4942626953125) rotate(0 110.28125 47.6328125)"><path d="M23.82 0 C61.47 -0.69, 93.52 4.98, 196.75 0 C216.1 2.95, 223.17 4.92, 220.56 23.82 C224.42 39.65, 219.59 49.22, 220.56 71.45 C219.08 90.46, 214.22 93.4, 196.75 95.27 C147.6 97.33, 98.46 99.1, 23.82 95.27 C7.29 95.04, 2.09 89.95, 0 71.45 C2.45 56.24, 2.75 44.41, 0 23.82 C0.67 10.72, 4.9 -3.22, 23.82 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M23.82 0 C73.46 0.23, 122.54 1.22, 196.75 0 M23.82 0 C70 0.09, 116.01 0.21, 196.75 0 M196.75 0 C213.09 -1.96, 219.85 9.16, 220.56 23.82 M196.75 0 C213.11 1.41, 220.05 7.44, 220.56 23.82 M220.56 23.82 C219.35 39.84, 220.74 55.1, 220.56 71.45 M220.56 23.82 C221.36 41.8, 220.53 62.25, 220.56 71.45 M220.56 71.45 C220.81 86.59, 213.06 93.69, 196.75 95.27 M220.56 71.45 C221.05 85.71, 210.41 93.9, 196.75 95.27 M196.75 95.27 C158.77 95.3, 116.48 95.21, 23.82 95.27 M196.75 95.27 C151.77 95.73, 105.1 95.39, 23.82 95.27 M23.82 95.27 C8.09 97.01, -1.6 86.27, 0 71.45 M23.82 95.27 C6.69 97.13, -1.41 85.29, 0 71.45 M0 71.45 C0.19 59.05, 0.6 44.44, 0 23.82 M0 71.45 C0.06 53.44, -0.92 36.28, 0 23.82 M0 23.82 C0.36 7.78, 8.38 -1.5, 23.82 0 M0 23.82 C-0.1 8.68, 5.78 -2.16, 23.82 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(839.5780334472656 415.6270751953125) rotate(0 93.33993530273438 12.5)"><text x="93.33993530273438" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Gateway Controller</text></g><g stroke-linecap="round" transform="translate(939.5 142.9864501953125) rotate(0 81.77734375 41.41015625)"><path d="M20.71 0 C56.95 1.65, 89.18 -0.68, 142.85 0 C159.8 -0.58, 166.6 10.18, 163.55 20.71 C161.08 33.25, 165.55 40.16, 163.55 62.12 C166.23 78.86, 156.24 80.86, 142.85 82.82 C99.65 80.64, 52.44 83.77, 20.71 82.82 C7.49 80.52, 1.3 75.62, 0 62.12 C-0.76 50.89, 2.19 39.45, 0 20.71 C2.33 4.4, 3.71 -0.81, 20.71 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M20.71 0 C65.19 -0.08, 112.71 -1.26, 142.85 0 M20.71 0 C46.04 0.33, 70.7 0.37, 142.85 0 M142.85 0 C157.33 0.63, 162.82 8.21, 163.55 20.71 M142.85 0 C157.68 0.45, 161.53 7.71, 163.55 20.71 M163.55 20.71 C165.74 33.72, 162.01 49.31, 163.55 62.12 M163.55 20.71 C163.68 31.27, 163.54 43.83, 163.55 62.12 M163.55 62.12 C164.24 75.7, 157.52 81.56, 142.85 82.82 M163.55 62.12 C164.79 76.17, 156.97 81.05, 142.85 82.82 M142.85 82.82 C99.61 85.16, 56.9 82.6, 20.71 82.82 M142.85 82.82 C111.28 81.63, 80.2 81.85, 20.71 82.82 M20.71 82.82 C7.12 82.37, 0.01 77.24, 0 62.12 M20.71 82.82 C5.96 81.25, 0.02 77.13, 0 62.12 M0 62.12 C0.89 47.15, -0.73 31.99, 0 20.71 M0 62.12 C0.69 46.92, -0.55 31.39, 0 20.71 M0 20.71 C1.74 6.85, 8.29 1.3, 20.71 0 M0 20.71 C-0.27 8.52, 8.72 -1.06, 20.71 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(994.1373672485352 171.8966064453125) rotate(0 27.139976501464844 12.5)"><text x="27.139976501464844" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Client</text></g><g stroke-linecap="round"><g transform="translate(922.86328125 183.162400055984) rotate(0 -105.361328125 -0.8692249303357471)"><path d="M0.05 -1.15 C-35.27 -1.48, -175.62 -1.12, -210.8 -1.08 M-1.38 0.86 C-36.97 0.11, -176.69 -2.25, -211.78 -2.85" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(922.86328125 183.162400055984) rotate(0 -105.361328125 -0.8692249303357471)"><path d="M-188.15 -11 C-199.38 -7.88, -205.73 -5.01, -211.78 -2.85 M-188.15 -11 C-196.2 -7.3, -205.19 -5.52, -211.78 -2.85" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(922.86328125 183.162400055984) rotate(0 -105.361328125 -0.8692249303357471)"><path d="M-188.44 6.1 C-199.68 2.44, -205.91 -1.47, -211.78 -2.85 M-188.44 6.1 C-196.43 3.45, -205.31 -1.13, -211.78 -2.85" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(769.3978710609954 147.5391845703125) rotate(0 51.191972689004615 12.5)"><text x="51.19197268900463" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Traffic</text></g><g stroke-linecap="round"><g transform="translate(928.5772506621181 349.6577824771475) rotate(188.5660498991342 -120.40162861425495 -46.92349377479326)"><path d="M0.36 0.29 C-18.72 -4.9, -73.42 -14.9, -113.8 -30.55 C-154.19 -46.2, -220.65 -83.14, -241.95 -93.61" stroke="#1e1e1e" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(928.5772506621181 349.6577824771475) rotate(188.5660498991342 -120.40162861425495 -46.92349377479326)"><path d="M-24.48 3.06 C-15.16 2.08, -6.74 -0.91, 0.36 0.29" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g><g transform="translate(928.5772506621181 349.6577824771475) rotate(188.5660498991342 -120.40162861425495 -46.92349377479326)"><path d="M-20.45 -13.56 C-12.49 -8.61, -5.51 -5.67, 0.36 0.29" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(808.2207168425398 268.5841064453125) rotate(0 65.25584565746021 12.5)"><text x="65.25584565746026" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Configures</text></g><g stroke-linecap="round"><g transform="translate(936.1958922859567 493.1307373046875) rotate(0 -27.263694847254442 54.974243164062386)"><path d="M-1.13 -0.25 C-2.06 8.87, 2.63 37.08, -6.23 55.34 C-15.09 73.6, -46.22 100.06, -54.29 109.32" stroke="#1e1e1e" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(936.1958922859567 493.1307373046875) rotate(0 -27.263694847254442 54.974243164062386)"><path d="M-43.75 86.65 C-46.66 90.48, -49.2 98.19, -54.29 109.32" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g><g transform="translate(936.1958922859567 493.1307373046875) rotate(0 -27.263694847254442 54.974243164062386)"><path d="M-31.64 98.73 C-37.62 99.45, -43.17 104.16, -54.29 109.32" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(916.1386855925398 541.3812670878817) rotate(0 65.25584565746021 12.5)"><text x="65.25584565746026" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Watches</text></g><g stroke-linecap="round"><g transform="translate(588.3232087702838 481.6697998046875) rotate(0 121.13727580091177 53.65456432845673)"><path d="M0.47 -0.11 C23.69 4.93, 100.2 12.29, 140.47 30.06 C180.75 47.83, 225.13 93.74, 242.12 106.51" stroke="#1e1e1e" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(588.3232087702838 481.6697998046875) rotate(0 121.13727580091177 53.65456432845673)"><path d="M218.74 97.67 C227.73 101.01, 237.6 104.27, 242.12 106.51" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g><g transform="translate(588.3232087702838 481.6697998046875) rotate(0 121.13727580091177 53.65456432845673)"><path d="M229.89 84.71 C234.49 93.18, 239.98 101.53, 242.12 106.51" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(548.2324355925398 511.3304858378817) rotate(0 65.25584565746027 12.5)"><text x="65.25584565746026" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Watches</text></g><g stroke-linecap="round"><g transform="translate(576.5876850571794 482.7557373046875) rotate(0 -51.44594701271518 58.185546875)"><path d="M0.29 0.13 C-8.59 7.07, -36.33 21.81, -53.51 41.35 C-70.7 60.88, -94.76 105, -102.82 117.32" stroke="#1e1e1e" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(576.5876850571794 482.7557373046875) rotate(0 -51.44594701271518 58.185546875)"><path d="M-98 92.79 C-99.21 99.92, -98.9 106.64, -102.82 117.32" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g><g transform="translate(576.5876850571794 482.7557373046875) rotate(0 -51.44594701271518 58.185546875)"><path d="M-83.36 101.63 C-88.64 106.32, -92.43 110.57, -102.82 117.32" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g stroke-linecap="round" transform="translate(319.9375000000001 612.9627685546875) rotate(0 196.5078125 67.5)"><path d="M32 0 C127.13 2.17, 224.31 1.2, 361.02 0 C381.26 -2.23, 396.05 9.95, 393.02 32 C392.75 47.4, 390.84 64.23, 393.02 103 C390.78 124.97, 379.49 134.65, 361.02 135 C259.59 135.34, 162.24 135.32, 32 135 C12.11 132, 1.72 125.61, 0 103 C1.89 83.85, 1.87 72.43, 0 32 C-3.44 11.92, 9.2 -1.19, 32 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M32 0 C106.07 -1.26, 182 0.52, 361.02 0 M32 0 C104.51 -0.82, 177.46 -0.62, 361.02 0 M361.02 0 C384.32 -1.79, 394.01 10.59, 393.02 32 M361.02 0 C380.92 -0.61, 390.82 11.87, 393.02 32 M393.02 32 C392.32 50.05, 395.41 68.55, 393.02 103 M393.02 32 C392.9 60.8, 393.6 88.87, 393.02 103 M393.02 103 C394.39 124, 381.1 136.9, 361.02 135 M393.02 103 C391.38 122.77, 383.09 133.82, 361.02 135 M361.02 135 C269.17 135.48, 175.48 134.2, 32 135 M361.02 135 C293.83 133.74, 226.2 133.19, 32 135 M32 135 C11.51 134.85, 0.4 125.7, 0 103 M32 135 C8.6 136.46, 1.03 122.73, 0 103 M0 103 C-0.97 75.24, 1.04 47.9, 0 32 M0 103 C-0.29 85.46, 1.51 67.2, 0 32 M0 32 C1.75 11.96, 11.27 0.67, 32 0 M0 32 C0.96 9.77, 10.61 1.16, 32 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g transform="translate(324.9375000000001 630.4627685546875) rotate(0 188.9198760986328 50)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">         InferenceModel API</text><text x="0" y="42.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> Defines</text><text x="0" y="67.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> - the model/adapter to serve</text><text x="0" y="92.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> - the serving objectives for the model</text></g><g stroke-linecap="round"><g transform="translate(466.70349253341556 449.71871084230554) rotate(0 -133.21484375 45.69419410734173)"><path d="M0.85 -1.12 C-25.83 1.77, -116.7 1.09, -161.23 16.46 C-205.76 31.83, -248.8 78.57, -266.33 91.1" stroke="#2f9e44" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(466.70349253341556 449.71871084230554) rotate(0 -133.21484375 45.69419410734173)"><path d="M-22.02 8.98 C-19.1 7.61, -11.91 4.81, 0.85 -1.12" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g><g transform="translate(466.70349253341556 449.71871084230554) rotate(0 -133.21484375 45.69419410734173)"><path d="M-23.16 -8.08 C-20.13 -5.94, -12.71 -5.22, 0.85 -1.12" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(277.3282506200807 477.1658935546875) rotate(0 89.76159312991925 25)"><text x="89.76159312991922" y="17.5" font-family="Comic Shanns, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Observability</text><text x="89.76159312991922" y="42.5" font-family="Comic Shanns, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Metrics Scraping</text></g><g stroke-linecap="round" transform="translate(10 530.4119873046875) rotate(0 85.671875 55)"><path d="M27.5 0 C57.96 0.23, 92.07 -2.16, 143.84 0 C161.98 -1.62, 171.53 10.07, 171.34 27.5 C172.01 46.69, 172.38 68.01, 171.34 82.5 C169.13 104.28, 159.03 113.05, 143.84 110 C96.78 106.99, 54.06 111.19, 27.5 110 C8.1 113.16, -3.25 101.52, 0 82.5 C3.07 64.43, 1.44 46.39, 0 27.5 C-1.67 6.06, 12.67 3.19, 27.5 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M27.5 0 C58.62 0.1, 86.75 -0.75, 143.84 0 M27.5 0 C66.17 1.24, 103.86 0.14, 143.84 0 M143.84 0 C160.73 1.75, 169.79 10.1, 171.34 27.5 M143.84 0 C162.38 2.15, 171.96 8.78, 171.34 27.5 M171.34 27.5 C170.44 50.01, 172.38 71.02, 171.34 82.5 M171.34 27.5 C172.51 49.03, 171.57 70.72, 171.34 82.5 M171.34 82.5 C171.08 100.74, 161.79 108.79, 143.84 110 M171.34 82.5 C169.18 99.21, 163.59 112.09, 143.84 110 M143.84 110 C100.17 110.08, 56.23 110.56, 27.5 110 M143.84 110 C97.23 108.17, 51.87 108.41, 27.5 110 M27.5 110 C8.79 111.81, -1.3 100.22, 0 82.5 M27.5 110 C11.27 110.65, -0.82 102.29, 0 82.5 M0 82.5 C1.49 66.6, -0.48 54.73, 0 27.5 M0 82.5 C-0.44 69.52, 0.7 54.3, 0 27.5 M0 27.5 C-1.19 9.05, 11.1 -1.12, 27.5 0 M0 27.5 C-1.28 8.1, 10.63 1.93, 27.5 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(33.09192307293415 560.4119873046875) rotate(0 62.57995192706585 25)"><text x="62.57995192706585" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Observability</text><text x="62.57995192706585" y="42.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Dashboards</text></g><g stroke-linecap="round" transform="translate(1188.15966796875 422.12890625) rotate(0 19.009765625 19.9765625)"><path d="M9.5 0 C17.2 -1.91, 23.8 -2.55, 28.51 0 C34.45 -2.93, 40.84 1.97, 38.02 9.5 C35.2 16.34, 40.22 20.84, 38.02 30.45 C40.35 33.57, 31.7 36.44, 28.51 39.95 C20.78 41.88, 17.07 42.29, 9.5 39.95 C3.11 38.32, 3.04 36.29, 0 30.45 C-1.02 21.62, 0.3 22.26, 0 9.5 C3.55 3.04, 4.96 -2.37, 9.5 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M9.5 0 C12.18 -0.35, 19.86 1.97, 28.51 0 M9.5 0 C14.27 -0.61, 17.82 -0.66, 28.51 0 M28.51 0 C34.98 1.32, 38.29 3.39, 38.02 9.5 M28.51 0 C34.94 -2.13, 36.52 2.08, 38.02 9.5 M38.02 9.5 C37.4 16.48, 36.07 22.88, 38.02 30.45 M38.02 9.5 C37.21 16.76, 37.8 23.99, 38.02 30.45 M38.02 30.45 C37.64 35.02, 33.72 40.39, 28.51 39.95 M38.02 30.45 C36.06 34.72, 37 37.72, 28.51 39.95 M28.51 39.95 C22.61 40.79, 14.26 41.35, 9.5 39.95 M28.51 39.95 C22.65 39.96, 14.96 39.51, 9.5 39.95 M9.5 39.95 C3.7 41.27, 0.1 35.19, 0 30.45 M9.5 39.95 C5.16 37.7, -1.03 36.06, 0 30.45 M0 30.45 C1.08 24.65, -0.89 20.64, 0 9.5 M0 30.45 C-0.05 22.97, 0.57 14.93, 0 9.5 M0 9.5 C1.06 3.51, 1.7 -1.87, 9.5 0 M0 9.5 C1.87 3.84, 3.92 -0.55, 9.5 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(1240.3881973112898 420.1015625) rotate(0 92.18748628246021 25)"><text x="92.18748628246026" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Standard Gateway</text><text x="92.18748628246026" y="42.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Elements</text></g><g stroke-linecap="round" transform="translate(1189.40771484375 494.0390625) rotate(0 19.009765625 19.9765625)"><path d="M9.5 0 C16.94 -3.63, 19.26 -2.83, 28.51 0 C36.94 1.41, 34.54 6.28, 38.02 9.5 C41.52 11.8, 36.14 16.95, 38.02 30.45 C40.04 37.07, 32.03 36.51, 28.51 39.95 C26.01 36.63, 16.57 40.91, 9.5 39.95 C4.3 43.02, -0.42 33.87, 0 30.45 C0.8 22.84, 0.86 14.53, 0 9.5 C0.66 5.06, -0.06 -0.13, 9.5 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M9.5 0 C14.98 1.17, 21.64 0.19, 28.51 0 M9.5 0 C13.88 0.31, 19.36 0.96, 28.51 0 M28.51 0 C35.95 -1.88, 37.85 4.17, 38.02 9.5 M28.51 0 C36.74 -1.67, 37.97 1.05, 38.02 9.5 M38.02 9.5 C36.58 16.46, 39.49 20.96, 38.02 30.45 M38.02 9.5 C38.5 16.62, 38.74 26.02, 38.02 30.45 M38.02 30.45 C36.7 37.35, 35.52 39.15, 28.51 39.95 M38.02 30.45 C36.32 38.33, 32.93 38.91, 28.51 39.95 M28.51 39.95 C21.83 40.67, 16.54 38.71, 9.5 39.95 M28.51 39.95 C24.82 38.9, 19.76 40.06, 9.5 39.95 M9.5 39.95 C3.91 41.69, -0.87 36.75, 0 30.45 M9.5 39.95 C1.02 40.41, 1.67 38.9, 0 30.45 M0 30.45 C0.31 24.1, -1.79 18.3, 0 9.5 M0 30.45 C-0.07 23.16, -0.08 13.24, 0 9.5 M0 9.5 C0.94 3.17, 1.28 1.06, 9.5 0 M0 9.5 C1.08 4.86, 5.08 -1.29, 9.5 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(1243.2768691862898 488.15234375) rotate(0 99.67576753246021 25)"><text x="99.67576753246021" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Inference Extension</text><text x="99.67576753246021" y="42.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Elements</text></g><g transform="translate(420.6089004362898 10) rotate(0 178.3730331574602 22.5)"><text x="178.3730331574602" y="31.716" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="36px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Inference Gateway</text></g></svg>
\ No newline at end of file
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1162.7099609375 654.745849609375" width="1162.7099609375" height="654.745849609375"><!-- svg-source:excalidraw --><metadata></metadata><defs><style class="style-fonts">
+      @font-face { font-family: Excalifont; src: url(data:font/woff2;base64,d09GMgABAAAAAB24AA4AAAAANKAAAB1hAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbjgwcgXIGYACBHBEICs48ugALYgABNgIkA4FABCAFgxgHIBsPKSMDdYrTCofsLxO4w8gHN0BNbIcMe0A7YXjmsBvrktWKoiXr/EcoaXh+br33/9//i/qrIMZG5CgZvUhyjMiy0OZOwCbsulIw7xpFj/Mabe4M9CqshiJ/j5vb1298nWgqTH1N0xBCExTCEaTHC3jtZkcIqQD+f9KtPvm/g9ZOtfoqlRosv73qV1f0k3amfRKBwC6TBNvdE2DNTmUy+b+cpnTVXP/MCAILlmU7tBAvYREMhVPa12PvPcZX5yp2nCWhIclrnHUWgEeagg+/5m71pG2o6RMkEUIhktKXzN+vtXofr59GvHMiIZp0GolSlt2zt4vZv0VMdmji3TwkhtDMpB3tSF4akRRoxKuZSCmJdaim79ui6s9F1GUVzZyj4LB9RwACgIkAIOiYEAgKQfC6AKDT0sMu15QsIHt0dTQB2VtHdSOQvcpntgAZDABAPMp8PDtaANUKgJRj5LgHhwBUBuT0l+HHTPk+1MTkwPQdQBH8+vv/mNcUaPP0xwONozWd9wUdT/dJm772jjLXOyByuozDnG17eB9A6shfA2LNPi5R8vRZbutAbDHsnMP0P7+3+Z4606l2B+pDw8w3Bg3f9cr9YcDcq0BN1+tmvC3Tw3y0+g9Rx5DcDQCCVgVaiqIxas1tFOJ2/C7179zNjWHmAsD0oSA5DBUNHQsHF4mHT0BITEJKQcmdihc1DT/+AgTK7dSoICQ+MQCgRFigjCUMgKwkABgpAoEyAHyWI4CQImIQAlUJmYR4WESYi40DiAQkDQok4mQIYl37KZB2mdmk0zEEhQIWNkAHLkqFSCCYVyYaOKbIE8THJDEiBZazRw40Xh8Rr0+eftuMRo2e5oNDHOMRzBITFBUxxMEQDyMETjEiYjgJppFhChXGqTHOGxMCaCJGYBgAgCE2feYVRPlOERQQZevSleKEQX+GSaEJfBO83mvLgeCzo6qFOwxBDrJcdpEYgegxJiwyz+aDBCuA16oEDgGVtixUQAR3D9QkQKdsRMk19ug4IOac6ty6LFdMEICAI2NNoxAbQ9IkDLiygJlFy5pRUFtRHgCSj6OBd2FeAK/QrOabLQ2M8tC1/Jco61LjGdg5ioQ/dkI9PiHkogAQuMccMabvYtxwodg8+AkSIoqBhY1DKqcsubr2tIVQX52lSZwiXaao/JOcnjr56it/+OVzzx57+ujP96f7GNh9NXXIA6AdojIRINGOhYZwJMSWGgqRRVTNeDPkXNdAc9XOaiJCTw0Gh7hp7NnCJJNbp6sytkrpF+2Zkd4eLvAWR8ax/QSZOSaZQqRJwfMzSd38OSFkpL4w2ZZe6Ajzj86WamerP95I75M3ady68NtcYegBwOmCfvm2bUYahseDe15qpXi5OwFJXdo90fUch/KNN9oqb1iFOQGg2e35Lc2LYzR7l8XVPKLNZo2nxRGNvmSkPsYnGLdDPJT9IxBdJSUYjepQIW31//ORSpM7HXryVzE2srmAAQ1YyYQAf3NQuKGfk8P1/sEr+jHZpN4NI2mebL3HXOSoTUqSSbK4O8PjbUM1W/XP6sUoDsBncqNSVvqG7H+ma4YiFTp/SkLzNbpCPJWkmmYFLUlSgps3AV6CFOOF1lFeZr6xtaV5F8jYqKtUbsBFFxYvMgGRCi3LwmgCHAGATMCu5wL8psbxOI5p/aK7MMBgwgCsJZmf2syn2CRb1U9IAlrmDs0UxLL4oDjlS3Ou9h7vCQn1IpCjIDEHYJgTseJGhtQjjMswSI6p58MZjsfoaoKvZp5STRJa93PRjfkU9WmtZtOvGiGFqwnO/5kv5iPgJiM7c8eo4F4IG9991yrMdyiLJ+L89imrEuIgk3PmnUAWUGmmBEBXSG21mGsurYnxNMcxnVE1jl9QfjJGXP2k+tprdcyA0G2wALYDFdOboXLG+bTJXNt4Qw4KcFV6EKAZnP4GQFjjK/EKzTgqiB4ATFkBHj5sw4jcBNsn8bQJupeOrO/ybwszuvpjMlRufXTv7ooeBTvBTfMlGC5mH8/44SL3UZ53jXwtNnAchhgRcsxj/HjUADYH0JzOX2xlNOJaMUaSHEkgSZJO0R0j08sZ5T7NcJljx7FwORnKEASm2W5LsiDhEkjSFNpsAi66irBwsalCK7QwuqBrEj4GaVoqXdEPl2QO5spupfenlxYKd7nmtWzSpWtIKWagxwDcLmA1QcoortEJrRBjaFmC4xduQkTS9cskzFXKVY+Ekr/JYLC42aD1v8mHBgZgmmbbtCE9EGrj88w3uBZxrU6NI0kVtHC1KTBzerdJnT5VIa5iijHDwbKSE+9hTH6XecO6yM/ljOuY6Y8jxVA4JWomwKh9XhQd33jzoL8YW8mPzSV5AhJBBzvyNoBruhh3B7fS8rC+Kb6WoN9IyUgL70yqYdQRJShvlnN4lguTI+usMD10bwLumteTe3Nomi5s/5pxg+M2E8Gt5nyPEZnnRRmZAKsATCmr341SsimGfbpWxvLGxyrj03tqmBOrea8S7o2OqzHifnyjvelfqEf94xfoucKkKCOJggA0AzPheNcynPP2RJstPvrR88SJl1PvSkslYjcaAOuLT/pJK64L8zimKgwNxZvIH82iZ2IwIW0X5EgqVfiYPoZMwGzSMUsAp1DXlRqJ9ZNxw5uKRZpyozs6z72DuztKgKtI6zwI64+Qo93MVFBw2oITINZWF+5O95sffVRTmufQk4yUjorA7dlb8qRm2sAGd2W/BEUiaaU22nPCs6ExKIEZ1HVeIdu3/Rbt8jvHme4hVcfQgmqCsY4ZXsZV+Q07RLCgT2phwwQp4+nx0bB3QbbW8XIwO5gbLt2TlR1uRXwv++PzQmqyzWTD8eGHlfp8lk0Em0nJqBiP7hdTSX4FJgZr2QLTwfcbOWpfJfZspdl9cHqPV7NraTnwZB9kYJOY0FWYvp0Vqx4OPk8yo4WpII5M67JCJMw1t8icZUr9bOssX+lcoBEXIwOv4WB3Q9R8JjvKB8EwwwGAND/Gxv6Eubmn9i2kaGGIJHthvMTPF65n+H4cXWQfaUl+ccUXFrNPZ19ezT7NFOfm4iWzZWSdILTClRWU3dGiL67InaR0rEnM7ZXYFhE7HPZ13qYLcbP74/g4j2lzhtHysNis1y9Sj6SLMiBzVjOj1VmmP57FpMuvPydzSRYc2VnNFGEGfzxRGvXU2Bi3+Wr3Ul3RbIsLyiHvlfKTzXyqz49vIXVWgJAkoU/SnUEJAEwmjSBBir/pL7bLyVy11mGyQXtzdlKAJVlcyVU7pV8mDCZHQJLzJHp+y6FdfjlX+/nei+Q4jmUhC4IcIttVOBuWLu9ku/MB0TAX+RWi5yRd06IbOjoWjIfxJK7Cf7oyIrJIjSeOqqiIrncJi1VXIJRKc7K5d7Uccanl7ZE3lkj+kl/MG+m6Fq33j3GI80pp/ZyEed5HfbwxmX8uzq7/usUNvuHELZkdfhK41wCetdF8+VlONDI8rA0OWVGPeFIJmNwuTNWVae50RF4T341z3sd6tl9kWW8gNLEerM5qzb8s9vn0Et8TIVUWFm6i0GOsCLJuV0GA+lQlX3QL9pDi4/7uo+GxuqUnc06fa6vGrHy77ne769kgIKlK/pp9WQwlSCAZKl9XjvOZoCNColsiMIClNxuH2DFaI9STZNIkmewXv3UjTj2VRK+PlRIIYlXgjQ3K/T4dH+ZwaCl50RRdIQAI6g/+rq9PtahFt5pbSGVn8xUDGAWPm4rzYfJ9u0dsKUEDJLAug9sVcIiTn8G0bZtYeXmL+9CID1++f/eb8zXa7JNpfqokmGAYyINf1UKh0eOP1mvB0Y1q8oeeD1ucD7mvcK+UlSeKt24cLyoVPsP1HAf+6rBUp2aIy9V6utEva3yBHVonXzJ4xODar3eP7336cHcoCBhIMiKlaenaBGAAPWVgMF2z+yXfVhdi3K8WGRxitARRb3GH3j/E7e3wCVIGd0iakxqdwifx8T8Lq3CllZ1fpyQfmqMgAHDxRlbOC1G7l/bmS/MK/b2m2fFoKiQa5IiI1L7pAv1q7dO6O64OFczw5exJXP1kNjEAPWIgFyu+pIqYw9BgAGq+zkhnSzneg0ny8jMYLckoIuTblRxmcF1Xz75Nwss+F1l0aS/3KW+jF52vMhF6cxhaSM0UPtv1fQdDbIV4OCGgvZxNdkpQlzYZ3Z+3Q+G5WHvSPscG31JyHg+8FCPlO86G0+/QaPruDOuIPBw70V7YBCMBILfdrsvgIcID4eXL6gnPFze83XIazWwpdoRgEhH3N2g92hokf6osDzaElxVUro4f8H4+yKfZCelwIsjvcUd6IUMormguH+cvmWvk98hhn8szjNQs7jpmIyGqMze478Rgb7A1jyA8EwYFA8BN1D+elA5AFCiI6uxeqC3p5CbAW9D/tsmK6K42Iz69H0pZ2WyErStc6yKFhzKUevXgls5xv7Ph1XK54zjU05zW8EwDXAEYtNk+ME1X9gv/p74KO/ColO9Fb2YcG9kYIev1ISUXYRRENr3PMI6Nxj1SQ3TBT2qf87sv43jy6fwqrBQp49eL5vteWrP23iA1RI8PsYuXa5UJuze3qbjqdbjcZ3AwQnqIsOm3QyEQULPBsZFVg0DlpLxY0MWS+P/LmN5kVWXxk7FRzA43F3+QbUgLWuoBp40br/9m3/Akm55M9iR+6krbaNBoyJLueDReYM8xzyxt+ijBspJmZJWZ9z8e5p5J+Za74dzby5lLQes48RjnU6FtBVTvaJg6JN9NGMmt7jntOSs+M78CJPfWR1KAt9TD1snwYqW5ybNSuoGWpwx5fySrFtRfIre8qxTbH4oFT4eJO2W79lSM5U/VLBkUlfn0f2UGQQeOfS4pfr8X21kygMjMYNXn+cpI0t7xYOgwI+PZleWaXP+YWdYVTWd0BT9qw6hAGmis+U+59MtSrufuMX8Fh5O/tBZfp0nNi0/M5HqrNU7f4MV0ng/zRcHHZizMLRvJQk+/c7qDNqIMEZ+MqflG41rDj9WEJj1cL8zj+DahVtiLLgDScNaJv2c6mBMK+oZsuM7cJ9osYDDv4mEfV1Ud5B7y4jsvluQ+mbX70Y4gi+m5oAh2w9a2YcEngKjneLnhECIVss1shDcw1quBDPjOb9rwVNJBoWbxt5zfjz/G2zyMnVePV2mDQW7wc0/Tz9r8tu3ABNbDuGW+Ex8as3cI6wsHjQUGRW2nB47M5mLIXU/Ls5bFPgu/Ske+kNWZSC6AF49b6rJWFk+Q9KJ//n9iKdiU5owwtCiGAOrC16F8tjW7Szo3Y0myBDg871M/6qm6dBQZdra7jh3DKeSsFwW1dCtCF1PP2GhnIfBKETt9jkbfkDP2PjN59Hmz+zKyrS6rl/6j0uu22xeul527Y3CvIldx1HOs/87fSa9JCONZswlKRmhSbmVPYYuCMM/4FBoSYAFm5DtakrxpmZ+CXUzBdHa+D18dT+RTTVQiP7s0/A5Fb/amneTaJoR/Hjo+dOZwj2yXZsaGjZu+pyRGje8J1Yy0YlbxPpPo+Otqoratxi8QLVGYOcP04VHT2He1MyZdi7Crs8Tpco3L68OlduxSebsecXfi3KpZOCUNzeJc+iNh3sH+NZyJsvP5e5c0Z4Bsv/Lx+6QyVe/XpygEs5pmpFoqdM2u2sbZDfbDcRlqvN38m4C+Nw0hZn76otd/4JDMXFGM2fWZZjJyhbDFoTJGjYFSrJJiACfUbp+2QW3f8mxiMAvNGjR7LKaT9d6OJKrvc5AvjVowUCvNCjpEfmThtNt/ZVPN9Jls8nhqBDUioHxxihBwc9pGdgTuzgr9sf+2xHHTdblWc/QezkdlYSjXxEWhGXZ7/N1G1eMY8pWziUXCwTOR7xK+K8onOwQULaqlCCvcNwB/8IxL62GPVFMH7Fjwvw6tuiByrjApNKAkkIqXwj83BjH4e1lJB/7Je+RXrODT8lv+UnvCAjx3l2ulayEg5TWLaGhjMPjaPnH3myTnU927/PLNQUTOTED4oUvMYktpS2eeyjAjJAbSODlyZ9xulRV87HkevRJWJly6oWt3WrJXJlVoLjLxhz6/yyAu2/q+RBaoNQm/oB3vuucWbsTzRG0igHUM7Obus5yi6SEY6SYao3aKMIotFsTC4qFSbqpPT0CW0l4xt9sfFouWDOWLFLjJHKyHwdT1XtJklb2mODXI5Z6Ux/a2fF8+NVcc+r3cPBGQm9bfJdO2eTfCA+/kDKcGCrcnpnqH7KvtWjL6ENTwi4OgkV6QJF+T8huS6ftRl04XKWOdyN6WjW/Dm/kV6rUB1hLhsWSQa31297ykqtWoXh0uSYkVAw8Wnpg8gICRPl4neVf/eGy2eBlgAGtG3BFSPRiyFzNMRXrdBkxZBUKXAynSiaSpDr5b6MUNnvLeGArffeSth0m0v/o3ZlpCs5t95sdxrm4fbndq4Xz0w9srl9hAx+AL4+n1FT16BqW/BymCTn6d9vCCiBOpCjp+emuye2d/ZGLaspLHhrjmajAiNYVXwzQKHzsfzC7SOs3cdLio3W2620vIiVO+qPDbmCkuIvSU6mXorjYupY1uh1NJWABu9XSnws3ctt1tzP1MPkV/V0/5i8gFP1LptC17UMli1Sfcc2ADQ5Ow0sFXRtVj1aLiereAJxVmc8TzJ+ymSKkzwupR9q5D87bWmnkqd/XOAQlv5Tefe5G1KdrZ9Ht/JNqe/X5Wnb6JhcBwiIM7r8VC1sxIqu9AzegaH6ldbtXZvZKjaHd/fGLKrcgwz+/zLk/DerW6pJTV/33zDTiD3zVIvFc3XEvPFvpDf8tHgVWqATsnnSDrt+i+LSpcI04Tqwolq9np2EtACag4ZB1TR7wjMviY2rOMxeRVuKDajs4lIpKw8KG8Y21YvQzQGVU2v6RgWhHMXIhnyYX/sYQNP5Mb6Yp7FE6vgrMKdS5R/+Fm3+Ie7FTp2pZvTIkIzc/hjs/7ajyLtD36a0egOp32hfVm9jdkAShijcoyHlRyf3qBW1vWdotKff7Qj3vWTCRqxkfRC4+jL6z/c+C+b8QniDF238Owl6nwaCOlI4KQzC0GB3ih5ycPP8cz4gla+lvz0phTSb4JKIF2EbhWVJXG45YgcR/ec8k3RgCnhtmodk9V68tDchVyfZLb35GEoPk/aUsLx+YYG4/Y13bCU/w0NzB+vXA3YqNlVYcDn5yz6pqGhIwUyYPK0faMRG8sIx8VCcObbp5nH6xIeYu/dPwnU4dGJbjT4xRlpGNGP7NXwV9zKJ2PDXQlkvlL+Jp2oeCbsNrdYIQ+8Ky322+ekGdaMu9gvnCxlzu3P+YYbBRJM1ZIIo51DnU4kfkH3nr3KY/SFDpy+//ys+pdmXC2Niayg5VGtV/40rGA//TixoQA8FAoNwl3eYuls6kUqk6xmEH8nAoEs/nWqILmrXppWrmY94l58KkKBZPdtNQSHpaBrJkRGtsbY6dH5tU9TYuyAQpDy6DMOWlxvn7QaFWZY2Md79Z8TP6k9jAKSt2ps7ejB3vUQK7blu5ez57jUbX158A/wH0h1ftSQIeYY/rjE7/GCEcdi3mFIe5TARRjhYRrkWQeWoiI2K/8+BSdcaBsGILp7w/ZYuxhIlFuLWhzhYtEnnaBe95ORZ4/jOJZ2sHa03eeKz3oB7rL+aTTtV7fFzbPqwtGk7lkr+TbfYCllBNOIo+QKf/0PveDsLn1YhBVFQKREL8GcHiHwRoQWrrBKXIPzzK8OypRjzfPlHC7oYnvdzY1LSw/zZ7xkYi9LI8FzTPC3E+s9HnCDmcVse3vs5/d3hIeckUiSv+7AByUX6+0rDJofzvAJPFaFLc+OzPTOfYW+Gc8vqzAoTzzwcQiC9s4icz2Ka9S+X8IESqOFIdeCbSM975BG3151C5CGYk2QSt9jfakmoKk4/WaQi+4xw6W8sXjN+FCCYugM76SIYzvA7tECndkMQW10VlBrI+I9Q6IWjyO7GXNGwfzwL4y9Q7kYYyIOVBYGrnt5d08vw8fC6I6+fGZU9eOrEsapebD3C+UW72Zc85kTTNYEbQAqaSFZprnktvTt4en/DuE/JyYy+hEQsGMlPDSleAYQpfyamp5hiLvw3axCqd6GqIiXfzgtPbd5k/dHYz1SkoqSuOa7nmMNQSwo6Dp6GWvnFavSb3n3ob+xqNutmxeBnoayv7yqAM/Y/71nzteYvUN/vWHDb6bEpP6EsfDrR8kNi9UPK5u03ok++aIHDorw7CrFqqyggPdz31MZg2YqT4BDEhvvne0EWzraGubzPmM9LHRD1JBjQy6imjmxffO8y0sYmiWm9b+mrnov5YE1aQrYjtGQ3o8iYaYqsHNMzZ8HicXOuzWrMOaJ4xkzs6F7HlgS8UfyScKmQWsTjT9XJr4BOLb8Qksz5zrTsnQzSN/R7rDb+amEHw+zkCIVloPcjxamkDV/QK+uT6VY3wN5RgW9xKxYq0BCNMxYwis9RpimwWUERVTHK5iwb27xPtXFXaXCig02Wq7gHnItnA5na9ZATpErFXRsfunJuLZqAMVIWZgsPAva3Rhfyv3jegZiq+HImcH7Ug1ZssMkdaKC3K8+fcidSYF8UTvhx4zz7YLXcsoGfeOz3p59dKyp/8fy76fF2UsuUOQ7Z6LFgGBbqJQc+GkhjHfW2DPMZ25RlOOVPx02xTNz2OO6mo/rBPtC/ZB22o0oZMjhon974Gl5U+t3BFxsZWjo6cfkb2pjtA+dB4zvG2ZU7/Ahs0SHB6duJGhL5sfleps91gEJpk4EWNY/sfiaokLSZjf5e6x72hPZPihAQm0MLJZePATvip0qQ31CEbUmpgQ1w8VvmM05adJNYokX913HxAoVraX7RkS4K3D4lm2B694+eAmQY59dF5XLHUemSNWLgUq6AnUzscgDDVJG3t7P9zx8O4rlSR313bZlcJLv2Xim0Y8sNEUDnFbZ5hrzrIUr4q6YThAVnmatAacAF+yUQ/GReNU3cZlreGxcBuCe7PIABWZu4SYTWYVKxdaKev9TbnJho6aO96ow+SZjAfwlOeCq7eFZh6N/gXuzL5fru8/bGuPSFIZE6zfTwnnyF0xdcAevzt9SyNWn9ydXmPUrcu/X51zeyhINCeHirUPcfvei8ss16O7ZrqM0ab1GxYKL3NJl4eFNwOiiL95f01hvN4iFNl1ZJdHxaXwF4Gy56MZ3evW5hv/4tIR0bkVpmzJTyHgZqfHeo0nsyR6zfvxgxeuWaM9pZWX5YVNhnK6XbzEl3y6xIYH3EPL2IG2H+dtvn0191V0ei1mjluduUCiUKXOS2iP+A+J0bRJhhM+CIuKoSV4yejAdML1TNMZ0X5RqOnxU80xbe32vCHvRkJXfsHlR+rzKshbNOI9VsvMPdFjuQy0kjWb/j9dtGpy7xe8YSn9v1+YfCWgAA808uV5eMUqEtw6frwyGmXkJi8jfuDw3iZ71KCN/F+RL/SzGdbufsiRcu55hCT3+gQmBVKtQrqTIxQ6Fr//0wzGIPjsRn8U4tnbPcfSX02PEXUeH4BNPd1I5+ZOdRJqVg+389VHunEL6O/4ssqJZ/6v+3GEn9F/+9gjGYAgqMbWsc8gpZy4x1QG+gcA8VSXvxlMeGfP3/OnezMf+wuL/i80eE9kGgT+9Q07eBq7v1e1/9d6utpVwTID8FfgDPKdrfiFwgqGtA9AvogXE7AaE3YUTr/Ok1vu4k/9DUHTgNfHDIG28sHFE5eedwEi5xmPivklJZ/7nxcgoCiRHuGOfR9IKMiUiDaKiw2iy6NNKio5n9kmNHe++YGphcYCrE4IKh0nnrA5QKH4DftNaaRaV+GhyH/7MXqwFKEACp5oAIAmF65ySOBzOYJtWI7y1yPHqFXIKRKoAZ/uFQCLuSqVa1KvRqsWMwVxqVZrVk5OuQ45sbgOnVpmWtZDqGBaJLFs+pwubeqGVC4Kh7Aj+M5QWM9R/Ky74FHTWkmzTDZpwzpJNad1a8F0JG26NFBvxNU9CXwNwO9IwmgVRJyhQtvSg0qqdAzJHMF5xKAJm3vQuc4YVB9RNcyeQpVRJAoCmn6DAgAA); }
+      @font-face { font-family: Comic Shanns; src: url(data:font/woff2;base64,d09GMgABAAAAAA/cAAsAAAAAHUgAAA+OAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgQwRCAqffJpVCzIAATYCJAM0BCAFlRgHIBuuGaOibpNWNLK/PLDJkPnjqiFKaRLnjrIb6gm3G3y04yBHnnTnJjGJ4ZVO8/W3+/kYNWoqpsXv/YSb/ru7JEhCEqDQsIVCjYoLFadT0X7RthO3TkX4PzeRvHRi6tvtV5wQkwk7ArGL6IgcyWGeLHPf3m0sTx83evuLmwKQwNIE4mYyP4bbrbVsbd92qmWdTmxid/noCVABzbtfmtjkzX2iEuOQnp8w9+1q8Yp0UOCtABCYcOt/gPTwGdD/73+tlXb6wnLc2QC5i7ARKk4tvP3bPV1/u2YT7vwjmnRg4VR4dgMkDDpUJByRIrJhl4olJSK8yavUVOlXq6LZILTm1hhhjJX++OUFgIwNzQYa4AdXY8B+fWN0YtAGt2sCgv+++LlAAJ7zqowj1CwcCQzUzIp/M5WtaIUVCS6aUBm/MfhjNPJWk5oVsrZ1QFC+SK70rDNhhWcZcSiN6n+xvdvQQE9RTkZaLBKG3AZUTT5LUqGRPJ9+V2I+AOAHVoKcUR3h3NPGChyHih97b+lY1cXIkGqixDSpMsPKfFGt6WJjS0tcdWru525EsRX3Pooxx5Q9O58JUXiPlOcQRRb2NOdyNzSCKMe292E9LQ55F43Ie0UQBCI0yCwgG8IDApgPfTF7RehHRJqR9YwPi7LcIWvM4mz/VUxFvD1JSnKMsc6EtD+NAKDHA2EOESqMQORhWV5t8VHFttQOT6shvR0OifnLdhOfDMTrqm1RJQDB7FKkgkYVBaX+FmSsY8CYFUG8fsjLLsdMH2lIaFqPAkXKLW5IJ/M0Pcnt+sWtDENEnMQxANSQLu9+pbPIl/kC0rYUJAUH6F3GVmAr6n/ftMteLp6fb+50iwnk9rnfEAkP2hMAQK5j5seTEIN/NtrcPLB9PhljLzFf3x9DHNljnYOrvSDE1UrWy1Yx7xVMOB3C4zYQnWz5ATxWvOgjBbQrI2I/EyNIwgFiWcxrUJoakGrA2IAdsd08tot+gvHANua/+6s68rB6z4sd8t8DwGjtYizWTAnL3hliJ7rww230yYxZlADaAVQ57tNHMwT/x78xFw3EKV8Ce5ZtIWou+OdnWq30MwcRbe0QBwCoNrCdwZijinIcpYnQ7qaInYv0HiJuleNQvsIgX83c8l6nlW6GGUtthHH3BDt+5llMYz5cj324+EbAEEJAmg57O3nT55MRKog6DsJK7gQR2uXPABTMMX+tZY8QoXfnG2JaN8EtLnd3VdnfPyeUhrHw8LBi35K/5fpq1KHipPmgN7S1s2Toc87jGn9eMu5nfLta5HIeljvRJ/gwn89qU+eevtazLyNfwDN879U+DVXUgIBehmihVdZvRbdQPUTbcUffqazVtoiFvleOReZXjAK9LhvVgqYmLDeMhn3CvHJ0fdDJS4qVL8uztzybr22fl4w5qfsSnyVxgYi0A4CE+lsh+P3rrKHLZHgYbIlkqqazjFY3kXD1G3/AKtgrRKAqfPk8V/vb1V6e3rDx2fKqncd8fh1XhRhZuGKZlz2I57gMD4PltfAvaFADGp1cfLolAFFOr4t9eqva61rg3dHPufScOaU6cs9uZ8N+fg/IOIhTLHqIElrKh3lbnD0Mxp4WI14g+pcklUt5jOuG8PHkKjXrp1W92z6LqZkZicqwrJuvYuDDX/qvR4VZt/laYYWlg50doWRCeT9xAu2m9/eP4zYsdulf6a4YGdjdVZc8rtrdTaiR4l/hkCaUvWfb1K/nv3ah5SXn1OVpqavVupeps2YPV8+GKUTCz7yZC1D5cDHrp1qj1wueAETog8VKVVT5n6jo/LhU2uySE6/ci5HVMzJ+MDTQNKPdN6cDnZaql0tDNyd5FUP7QWZaNggE1Fu09TGdF7WjWhaTsr73OKFHNxdC5p5pHVhSX0yfp3CLxKC2lIPKJqL0kBOemoRiuhXTirYIuW4hvjVV7UhT5t46lbFrPSes/t9IIFNoflXERPx9c4DDZaBxrlSnTO2pnE07SHaLaBegaZDrRIRCL8t6tnNhmGqwuhtX1uO3GBuPseZ75Vj9eO3v4tzWPuoRTI6dq9TkbU2uzPYSMNZsSY5n53ObuP+zUji1T+mjtkpVjaK2XD1UWcusRNmDDeOpnBiuK1e1Az4Y1+b6RGTevBZCkURmoVzQbUCR3TtTrvIqjbQqiR9RMnmdHwVnNxTwgUWhTSKCjJ2pYg1D+0XbM8vDI9MLXq3zslgNNGIzBvQGdMl3gCdOS2bKFS5fvuoQhmtb9YSQCtQNj+BYM6+28jr3apUyZ85+z801ZxUhpaZ57vlCpLVZYka5LXCANpN6p0E5+nhJujDZIznTm+lp8jg55RskjeFpkvqI0SB8Rvm5Llo+H+llNR7/vcycyejt0WaDj0deRkx7j3R1WDvvsbYbbjZ3htbMjTwSYjn1vMHkeW5+OnbYfPTp1phAhz2xrTU6q200PP5zeIq3l0rJctVbGinFScdFjIVLn0e6tbB0zEuIHp3ufUXKtDYPHJqb29rcMdvb46txbh5nlP6Orh/gSaqrQ4It+ohTlkL4QitJshNPMvI9bMHZ0lhp5hmM+MtP3ZOhOrBpEDRB9ayl3xuMxCdP3IyQnmSfk+UadifPo/HRzUFXZmPiddNZhmAiquzjnRluLbbWDfv+zKV+ySxfvfpTDVa28fp/arCv/t0qp8hfoRRAsp8uZZjgla9b7vVso2BrPo30UvA1PXX2XEUATd/J8fi8ccmTECgJGJxb2MIWHlGYDz/dPHrfa80Y6g6GBLyIsxW4J6RrhWSKEBJ48Ird7n4nONc4GvLxEJPnQ/HNtnmZopVULzwaj/RTKTIHZjyRzaO2pYwwSgqlCCIvBksKH4TXceakYg2fiOFWTE3D5mYU1Rwi0sNSe6VGuienOzzCDeFvRk4NnPYlsn3rHKvdnOM6uOuLMEKk7I66Ml1zHUX4JVdLCC2cKNbPc9QGzN2d5ZphtjZzQosiiy21RBYQHoam4um4xOpt/H86r7UZQtCdtTTNvmEmGksdtJV0wH2gvRDopcWSmVe+yUEaeep/Aj/sf4umJfSF3uBmlHT88BmwZjkjKIKKw5PSU9ugUmRn0zTlvvLyEyLC4nPWEq/pHUIKmnhYjG2OjFEoOZMmUF1ocvv65ED4zni1MBQzUnQGk8/y8jcRI+21ZUYafkl38vzCM08cCaRIrNw6NrvCN8avwByX/mF7Di8wPYoS+2FtESHRtetwHqt2XAqIi43tRCoZOq1ZL9g906yZffDX0p+BND3/Xg8JEZfE8FYHQiluyXWLO08RjMQVvhmewc7EBmYYjgtUlbIYmR43CBi/Ga2gOkwbYzMVdpZn9Npj22Q15CSlcGpbyaOFnGps5fJlk331RSrRQydK8WcKRXtptW/ufMdS1a0/K2iKaOQU774KdsK3ePvELqYnZfwPHbvl96vM/q1FxtmP9ksMnRuUmhXQzDU8okUQrFUc08+VGCYTdahAJSopQBcbHmx6ygtPTEbNGcqVVXvGcJxWHCRrZYXCR5jdhehNTwXuoWTsCHsxyZIVSgWvdDXspSlDuwMnLvYKIxS//BSkMHGO0Z1z04ZU7HQracOzOXMe9VOr5jsWNm6aUSunBVZl1bna58TUqFRtG/rEsnxprZzh3zRhKPxH3bZXFvscGEl3YUQEcPzvFEzxB+scJ9/5t8nP6vFRdHl+1Ldq+QeT/9mUxPJKTxxKcX8uLaFoza516aWbQftnUf4CX37KyjCMXACm25rNyxz5bZRPG4bberSVQcF2dyaWm2K7NT3UOK8tz9rGPBrPqsZWLpRK7EutGf5VeXXmgn22Gl2/hvkxnAa6pM7x0NJ8Eteo8V2RrbcaWU5v0AiSfl2feosoCoHz3Sm6IJ3nUSFpOkC6xGu+uIrNUHfogsymZ7zwGEQbuAKICsBAsDHFeRsccb5DrWE8eDtf5iv+DWTnJ8zjGghxPs03XAdBoad9jP8Bf+fDQXgRpDqv5RN6DLnO99DNTkOG814eoZctNxsvwJAgTKM3eULsk30b83aR/YJ+TgOlz7zOPZM+8jjPnPrUzdJOsf76jMWUAtn3XMG3P9eHXMX9L2EVukXsa29zQgMAAGxdJvRoJSR+VLLkCQbghir3AgbgfnQFO98NXkjNBgAlDAAAgX8d67gamP9YTWFufxWcD3pjAwaOwDfvtLX8JtDIZhDRgGLiRDE1wOOIGgAkf9FqUTAABAFIxQCGACg01YRWFYDq9v9jKeLr31KMN3cp0VbnWApeSlOzWeby+zGQIRKgLAcPhlAo07JH3BV8hlQXr4/XoYqE8samYCBAL3glmAGq46FdHRAy6xprPamO6p2hZ4A5MlTZmu7Y8grHBA4ESx29auwpRd2zHPiZyy+Q7vSuCS2kebAuzrdixMY9fbvIJVOw4nl84bwYfMTL7hHObmzUeImBWpnK5AyxEVZQnY1Uh02qBlYFJEQ5skF1dVKRKlaWnjLAJyMICyW+p7a2ZCypgONAhmqHkYBH2BNmIeDOGc4pTWIbxw4ASht9MOTO8BQgzjUAHrEcE7mMXCKmJiRKQncU4kmMY+lUTkw4m3BuKVISqbKhBy53WCiDG7TGJBQChDGCWpo4qBqg5J/0oDrTZ4d86LNfIsg8OIJZtinEdGwCqFBAIoUdCFQsg7cNB5CCxFt8jLM16BIpPmqO4Z9PbGyHm4glXEz6Gy3xoQIkSJ3xscSoECuYaSTzmACnGbPJg1Czs/w2TTkruO1uIGLCd2x6R7U2lnbXzVCQ4sYzJL2Dg9IM5kqpUw/sQJmxOirGLhR4LEnB9pPKDpIXu0iaF5o4ciALG9AYBoHgnFJ7JDPbXq4iwhvMUkoE2WXTSiiKO8Zydt79J4m3aecICGKDlwBzknMXpFIB6kMwJk2Fw3ba7EyRSA7ISDs8Ix0vXTQI8Jg6Chei/cTqrQfbIsbOQYEom3BAdID4sxVyoVN47PTiIL7UrizaOLqBlmGMxi4L2VDiBLnSC3IgzLA9tszWtlaFQxigrTyRE+VjxxyQUskGfgGWflMRyx1HGIjryAik6YGVXY927Mk0IIgkOhW4xxwWH+mGI6st5EAfkIIuyE5WIwTUyW9hrEPCncKUN/wHVHsZjJIjqeNlEgbauHMQ9oDb0MpKkGUbd9I93Wu3EMgw36hlTosEzCsDCTUgQXpBqF3lRpAxiWUholtfWeVD1kSu1QJPxAOWGSKjG3kDkEYYaU58Ylk16KGNAHOIdXvAcTaqfZeEfHFhD4LqGBl3QF3GzB3rTE2fYhbVVLA1x8M4+pRge+jCQHzi0IUdg+IwjTi5Q1JjYGfSC+c13QIAAA==); }</style></defs><rect x="0" y="0" width="1162.7099609375" height="654.745849609375" fill="#ffffff"></rect><g stroke-linecap="round" transform="translate(68.21875 154.823974609375) rotate(0 57.140625 41.75)"><path d="M20.88 0 C40.07 -3.44, 67.81 3.23, 93.41 0 C108.58 -1.7, 113.64 4.43, 114.28 20.88 C110.37 31.89, 114.48 43.19, 114.28 62.63 C111.97 77.06, 110.19 79.94, 93.41 83.5 C76.29 85.88, 58.8 83.04, 20.88 83.5 C5.01 86.19, 3.57 75.81, 0 62.63 C2.8 49.69, 3.12 33.02, 0 20.88 C0.67 5.24, 5.02 3.06, 20.88 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M20.88 0 C38.48 1.33, 55.66 1.28, 93.41 0 M20.88 0 C44.6 -0.2, 69.08 0.17, 93.41 0 M93.41 0 C108.93 -0.66, 114.81 6.61, 114.28 20.88 M93.41 0 C108.53 1.09, 112.71 7.42, 114.28 20.88 M114.28 20.88 C112.83 36.64, 115.76 49.99, 114.28 62.63 M114.28 20.88 C113.33 33.37, 113.92 45.86, 114.28 62.63 M114.28 62.63 C115.09 77.36, 107.86 81.53, 93.41 83.5 M114.28 62.63 C116.05 77.36, 107.29 85.79, 93.41 83.5 M93.41 83.5 C67.37 84.88, 43.52 83.69, 20.88 83.5 M93.41 83.5 C64.39 82.39, 36.31 83.79, 20.88 83.5 M20.88 83.5 C7.14 83.77, 0.22 76.33, 0 62.63 M20.88 83.5 C7.36 81.6, 0.6 75.33, 0 62.63 M0 62.63 C-1.85 48.15, 1.08 32.11, 0 20.88 M0 62.63 C0.19 51.66, -0.9 39.69, 0 20.88 M0 20.88 C1.08 6.53, 5.03 -0.9, 20.88 0 M0 20.88 C0.95 6.51, 4.8 2.2, 20.88 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(85.1171875 141.370849609375) rotate(0 57.140625 41.75)"><path d="M20.88 0 C36.65 0.88, 53.33 -3.33, 93.41 0 C106.92 -1.99, 112.95 8.68, 114.28 20.88 C113.65 31.24, 112.8 40.44, 114.28 62.63 C112.86 74.18, 104.02 84.03, 93.41 83.5 C75.64 78.75, 55.15 82.05, 20.88 83.5 C6.55 81.54, 0.98 74.7, 0 62.63 C-1.9 48.94, -3.45 40.75, 0 20.88 C2.95 9.1, 6.34 -1.4, 20.88 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M20.88 0 C44.26 1.44, 63.6 0.29, 93.41 0 M20.88 0 C40.78 -0.21, 59.6 0.09, 93.41 0 M93.41 0 C105.83 0.69, 115.59 5.93, 114.28 20.88 M93.41 0 C107.36 -0.58, 116.13 6.78, 114.28 20.88 M114.28 20.88 C115.72 29.87, 113.43 41.74, 114.28 62.63 M114.28 20.88 C115.3 30.82, 114.91 42.41, 114.28 62.63 M114.28 62.63 C112.36 76.73, 105.74 83.18, 93.41 83.5 M114.28 62.63 C112.48 74.85, 108.46 83.79, 93.41 83.5 M93.41 83.5 C67.59 85.09, 44.24 83.88, 20.88 83.5 M93.41 83.5 C77.17 82.58, 58.4 83.6, 20.88 83.5 M20.88 83.5 C8.45 84.11, 0.55 76.75, 0 62.63 M20.88 83.5 C7.06 81.8, 0.99 74.25, 0 62.63 M0 62.63 C-1.18 51.77, 0.62 41.51, 0 20.88 M0 62.63 C0.34 46.95, -0.32 30.63, 0 20.88 M0 20.88 C-0.1 6.15, 6.07 -1.37, 20.88 0 M0 20.88 C0 7.01, 8.25 -0.1, 20.88 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(316.1015625 509.745849609375) rotate(0 186.5 67.5)"><path d="M32 0 C140.02 -4.99, 249.26 -6.46, 341 0 C361.27 3.21, 371.54 8.64, 373 32 C374.4 45.04, 373.03 60.55, 373 103 C370.4 126.18, 365.21 132.91, 341 135 C225.99 138.51, 106.01 138.75, 32 135 C11.12 135.2, 3.06 121.49, 0 103 C2.24 85.97, -1.84 69.24, 0 32 C-0.72 14.27, 9.6 1.86, 32 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M32 0 C147.2 2.31, 263.84 0.13, 341 0 M32 0 C152.79 -1.4, 273.68 -0.26, 341 0 M341 0 C363.24 1.89, 371.63 8.68, 373 32 M341 0 C361.89 1.32, 374.96 8.55, 373 32 M373 32 C373.51 49.51, 371.4 69.4, 373 103 M373 32 C371.89 53.55, 372.75 74.94, 373 103 M373 103 C372.91 124.05, 363.84 135.32, 341 135 M373 103 C371.37 125.1, 364.41 133.43, 341 135 M341 135 C243.35 136, 143.9 136.22, 32 135 M341 135 C252.05 134.58, 161.61 134.64, 32 135 M32 135 C9.49 136.67, -1.21 123.37, 0 103 M32 135 C12 134.37, -0.77 125.37, 0 103 M0 103 C0.14 78.38, -1.66 53.05, 0 32 M0 103 C-1 85.17, -0.34 65.21, 0 32 M0 32 C0.75 11.29, 10.4 -0.03, 32 0 M0 32 C-2.27 12.93, 10.36 -0.31, 32 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(330.0703124999999 496.929443359375) rotate(0 186.5 67.5)"><path d="M32 0 C99.75 -0.07, 161.54 3.63, 341 0 C363.88 -2.2, 374.83 7.14, 373 32 C369.67 56.51, 369.73 80.69, 373 103 C371.86 121.04, 365.88 135.99, 341 135 C256.53 132.69, 168.68 133, 32 135 C10.03 134.3, -0.87 127.4, 0 103 C1.64 86.22, 3 67.78, 0 32 C1.84 9.2, 14.11 0.61, 32 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M32 0 C115.52 1.4, 198.1 0.3, 341 0 M32 0 C146.69 2.05, 260.35 1.75, 341 0 M341 0 C364.02 1.02, 374.31 9.03, 373 32 M341 0 C363.28 1.65, 374.07 10.28, 373 32 M373 32 C373.05 49.43, 374.13 67.61, 373 103 M373 32 C373.56 53.48, 373.1 74.79, 373 103 M373 103 C371.81 123.87, 362.02 136.69, 341 135 M373 103 C371.99 126.23, 362.36 135.56, 341 135 M341 135 C247.91 132.51, 156.62 132.69, 32 135 M341 135 C261.96 134.72, 182.4 134.98, 32 135 M32 135 C11.59 136.42, 0.19 124.28, 0 103 M32 135 C8.96 137.09, -1.24 125.29, 0 103 M0 103 C0.44 84.06, -1.82 68.4, 0 32 M0 103 C1.27 79.48, 0.98 56.36, 0 32 M0 32 C0.16 12.48, 10.16 0.85, 32 0 M0 32 C-0.57 10.58, 9.84 0.71, 32 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(477.3994140625 247.83984375) rotate(0 110.28125 47.6328125)"><path d="M23.82 0 C71.25 1.44, 121.04 -1.23, 196.75 0 C215.34 2.43, 217.56 10.86, 220.56 23.82 C220.43 39.4, 220.37 62.4, 220.56 71.45 C220.84 86.46, 210.56 97.66, 196.75 95.27 C137.78 100.62, 81.78 96.46, 23.82 95.27 C10.36 97.47, -2.73 87.07, 0 71.45 C-2.96 52.81, 0.19 35.84, 0 23.82 C0.08 10.72, 6.94 1.73, 23.82 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M23.82 0 C67.79 -0.23, 115.28 2.19, 196.75 0 M23.82 0 C72.95 0.25, 121.65 -0.72, 196.75 0 M196.75 0 C211.99 -0.05, 222.44 6.28, 220.56 23.82 M196.75 0 C213.5 0.36, 222.09 8.09, 220.56 23.82 M220.56 23.82 C221.31 37.36, 220.25 56.1, 220.56 71.45 M220.56 23.82 C219.9 38.62, 220.14 51.22, 220.56 71.45 M220.56 71.45 C219.03 87.42, 210.82 93.29, 196.75 95.27 M220.56 71.45 C219.84 88.77, 212.6 93.46, 196.75 95.27 M196.75 95.27 C140.64 96.38, 87.94 95, 23.82 95.27 M196.75 95.27 C160.68 94.58, 125.89 94.95, 23.82 95.27 M23.82 95.27 C8.02 95.61, -0.4 87.6, 0 71.45 M23.82 95.27 C6.83 96.97, 0.75 88.96, 0 71.45 M0 71.45 C0.08 56.74, -0.66 41.56, 0 23.82 M0 71.45 C-0.02 54.9, -0.79 39.32, 0 23.82 M0 23.82 C-1.09 9.87, 7.36 -1.79, 23.82 0 M0 23.82 C-0.48 8.17, 9.74 0.58, 23.82 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g transform="translate(511.02071380615234 270.47265625) rotate(0 76.65995025634766 25)"><text x="76.65995025634766" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Endpoint Picker</text><text x="76.65995025634766" y="42.62" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Service</text></g><g stroke-linecap="round" transform="translate(102.2177734375 127.552734375) rotate(0 57.140625 41.75)"><path d="M20.88 0 C46.28 -0.94, 80.79 0.72, 93.41 0 C104.19 2.4, 117.1 10.26, 114.28 20.88 C117.53 35.09, 113.39 42.67, 114.28 62.63 C113.78 79.14, 109.16 85.65, 93.41 83.5 C76.92 81.02, 54.36 82.46, 20.88 83.5 C4.7 83.19, 3 78.05, 0 62.63 C1.68 42.54, -0.05 30.88, 0 20.88 C-3.48 6.36, 5.12 0.21, 20.88 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M20.88 0 C46.71 1.43, 72.02 0.45, 93.41 0 M20.88 0 C39.7 -0.76, 56.01 0.02, 93.41 0 M93.41 0 C107.38 -0.04, 112.83 5.4, 114.28 20.88 M93.41 0 C105.18 -1.7, 112.43 9.16, 114.28 20.88 M114.28 20.88 C114.06 31.68, 115.46 44.3, 114.28 62.63 M114.28 20.88 C114.08 36.13, 114.93 52.01, 114.28 62.63 M114.28 62.63 C114.53 77.24, 106.51 82.14, 93.41 83.5 M114.28 62.63 C113.73 75.85, 107.43 85.02, 93.41 83.5 M93.41 83.5 C73.07 83.17, 56.48 82.82, 20.88 83.5 M93.41 83.5 C73.98 83.5, 55.11 83.83, 20.88 83.5 M20.88 83.5 C8.61 83.03, 0.17 77.43, 0 62.63 M20.88 83.5 C7.32 83.09, -1.65 74.76, 0 62.63 M0 62.63 C1.3 47.78, -0.48 30.94, 0 20.88 M0 62.63 C-0.89 52.85, -0.46 41.69, 0 20.88 M0 20.88 C-1.45 5.25, 8.55 1.64, 20.88 0 M0 20.88 C0.61 4.94, 6.82 -1.54, 20.88 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(128.9084243774414 144.302734375) rotate(0 30.449974060058594 25)"><text x="30.449974060058594" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Model</text><text x="30.449974060058594" y="42.62" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Server</text></g><g stroke-linecap="round" transform="translate(470.3876953125 10) rotate(0 110.28125 47.6328125)"><path d="M23.82 0 C69.04 -0.44, 115.41 -2.92, 196.75 0 C211.63 1.35, 222.48 11.39, 220.56 23.82 C220.18 31.29, 219.35 45.04, 220.56 71.45 C222.5 85.21, 210.82 94.98, 196.75 95.27 C148.05 99.11, 107.88 97.98, 23.82 95.27 C8.15 91.93, -0.33 86.03, 0 71.45 C-0.17 62.04, 1.9 51.19, 0 23.82 C-1.35 11.01, 11.48 -1.99, 23.82 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M23.82 0 C80.54 1.26, 135.33 -1.37, 196.75 0 M23.82 0 C83.27 0.83, 144.24 0.1, 196.75 0 M196.75 0 C212.38 -1.16, 222.02 7.56, 220.56 23.82 M196.75 0 C210.97 -0.21, 218.68 7.7, 220.56 23.82 M220.56 23.82 C220.3 39.34, 220.95 54.89, 220.56 71.45 M220.56 23.82 C221.75 40.07, 221.52 55.58, 220.56 71.45 M220.56 71.45 C219.87 87.55, 213.15 94.55, 196.75 95.27 M220.56 71.45 C220.64 87.7, 212.04 93.53, 196.75 95.27 M196.75 95.27 C150.02 97.34, 100.19 98.1, 23.82 95.27 M196.75 95.27 C159.18 95.87, 122.12 97.55, 23.82 95.27 M23.82 95.27 C7.17 96.38, 0 86.34, 0 71.45 M23.82 95.27 C9.37 95.14, -1.77 87.34, 0 71.45 M0 71.45 C1.78 54.35, -0.91 36.58, 0 23.82 M0 71.45 C0.11 52.85, -0.74 36.39, 0 23.82 M0 23.82 C1.23 8.88, 8.75 -0.46, 23.82 0 M0 23.82 C-2.1 6.39, 6.03 -2.19, 23.82 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(481.6190081834793 45.1328125) rotate(0 99.04993712902069 12.5)"><text x="99.04993712902069" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">L7 Proxy / Gateway</text></g><g stroke-linecap="round"><g transform="translate(583.2613405725397 110.44140625) rotate(0 -0.07744763001983301 69.37890625)"><path d="M-1.19 0.76 C-0.89 23.95, 0.52 115.91, 0.88 139.07" stroke="#2f9e44" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(583.2613405725397 110.44140625) rotate(0 -0.07744763001983301 69.37890625)"><path d="M-8.03 115.71 C-4.77 122.76, -3.52 128.17, 0.88 139.07" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g><g transform="translate(583.2613405725397 110.44140625) rotate(0 -0.07744763001983301 69.37890625)"><path d="M9.07 115.45 C8.49 122.39, 5.9 127.85, 0.88 139.07" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g stroke-linecap="round" transform="translate(768.5498046874999 490.203125) rotate(0 192.08007812500006 67.5)"><path d="M32 0 C158.04 4.59, 289.17 2.11, 352.16 0 C374.5 2.14, 385.78 14.17, 384.16 32 C380.34 58.45, 384.72 90.14, 384.16 103 C384.95 121.39, 372.03 134.63, 352.16 135 C283.11 135.67, 217.71 136.84, 32 135 C10.4 134.18, -0.97 122.58, 0 103 C-2.31 73.54, 2.48 47.77, 0 32 C-0.77 8.01, 9.96 -0.29, 32 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M32 0 C125.72 -0.2, 220.61 0.88, 352.16 0 M32 0 C100.58 -2.23, 168.62 -2.12, 352.16 0 M352.16 0 C371.8 -0.78, 382.64 12.44, 384.16 32 M352.16 0 C373.2 1.21, 384.15 9.66, 384.16 32 M384.16 32 C383.15 60.37, 385.37 87.56, 384.16 103 M384.16 32 C384.71 58, 384.05 83.35, 384.16 103 M384.16 103 C384.41 125.28, 373.49 136.81, 352.16 135 M384.16 103 C385.42 122.08, 373.35 135.39, 352.16 135 M352.16 135 C252.85 132.7, 152.26 134.2, 32 135 M352.16 135 C277.01 137.27, 202.72 136.84, 32 135 M32 135 C9.75 134.61, 0.37 123.55, 0 103 M32 135 C10.58 134.83, 0.13 123.49, 0 103 M0 103 C-0.39 76.36, -0.28 46.02, 0 32 M0 103 C0.19 85.91, -1.05 68.06, 0 32 M0 32 C1.64 10.1, 11.49 -1.64, 32 0 M0 32 C-0.34 12.02, 8.7 -1.11, 32 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g transform="translate(773.5498046874999 507.703125) rotate(0 186.12994003295904 50)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">            InferencePool API</text><text x="0" y="42.62" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> Selects</text><text x="0" y="67.62" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> - the model servers (the endpoints)</text><text x="0" y="92.62" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> - the endpoint picker service</text></g><g stroke-linecap="round"><g transform="translate(462.5791015625 281.07421875) rotate(0 -121.759765625 -29.005859375)"><path d="M-0.98 0.09 C-24.45 -1.97, -100.69 -2.65, -141.04 -12.38 C-181.39 -22.1, -225.85 -50.8, -243.06 -58.27" stroke="#2f9e44" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(462.5791015625 281.07421875) rotate(0 -121.759765625 -29.005859375)"><path d="M-218.27 -55.08 C-225.22 -56.5, -232.35 -56.35, -243.06 -58.27" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g><g transform="translate(462.5791015625 281.07421875) rotate(0 -121.759765625 -29.005859375)"><path d="M-226.12 -39.89 C-230.82 -45.59, -235.69 -49.8, -243.06 -58.27" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(273.1737523901456 211.21875) rotate(0 68.55846812991925 25)"><text x="68.55846812991923" y="17.5" font-family="Comic Shanns, monospace, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Model Server</text><text x="68.55846812991923" y="42.5" font-family="Comic Shanns, monospace, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Protocol</text></g><g stroke-linecap="round"><g transform="translate(443.85546875 58.15234375) rotate(0 -112.228515625 29.22265625)"><path d="M-0.68 -1.1 C-20.79 -0.89, -83.63 -8.3, -120.94 1.71 C-158.25 11.72, -207.44 49.33, -224.56 58.94 M1.16 0.93 C-18.54 1.29, -80.92 -6.18, -118.67 3.14 C-156.43 12.46, -208 47.83, -225.37 56.86" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(443.85546875 58.15234375) rotate(0 -112.228515625 29.22265625)"><path d="M-209.44 37.6 C-215.6 41.42, -218.51 47.98, -225.37 56.86 M-209.44 37.6 C-215.11 44.17, -220.1 49.91, -225.37 56.86" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(443.85546875 58.15234375) rotate(0 -112.228515625 29.22265625)"><path d="M-200.78 52.35 C-209.39 52.05, -214.69 54.54, -225.37 56.86 M-200.78 52.35 C-209.52 53.95, -217.46 54.65, -225.37 56.86" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(275.7103710609954 18.6875) rotate(0 51.191972689004615 12.5)"><text x="51.19197268900463" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Traffic</text></g><g transform="translate(468.03412875362244 156.51953125) rotate(0 55.69806259269109 25)"><text x="55.698062592691095" y="17.5" font-family="Comic Shanns, monospace, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Extension</text><text x="55.698062592691095" y="42.5" font-family="Comic Shanns, monospace, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Protocol</text></g><g stroke-linecap="round" transform="translate(822.63671875 250.1328125) rotate(0 110.28125 47.6328125)"><path d="M23.82 0 C61.47 -0.69, 93.52 4.98, 196.75 0 C216.1 2.95, 223.17 4.92, 220.56 23.82 C224.42 39.65, 219.59 49.22, 220.56 71.45 C219.08 90.46, 214.22 93.4, 196.75 95.27 C147.6 97.33, 98.46 99.1, 23.82 95.27 C7.29 95.04, 2.09 89.95, 0 71.45 C2.45 56.24, 2.75 44.41, 0 23.82 C0.67 10.72, 4.9 -3.22, 23.82 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M23.82 0 C73.46 0.23, 122.54 1.22, 196.75 0 M23.82 0 C70 0.09, 116.01 0.21, 196.75 0 M196.75 0 C213.09 -1.96, 219.85 9.16, 220.56 23.82 M196.75 0 C213.11 1.41, 220.05 7.44, 220.56 23.82 M220.56 23.82 C219.35 39.84, 220.74 55.1, 220.56 71.45 M220.56 23.82 C221.36 41.8, 220.53 62.25, 220.56 71.45 M220.56 71.45 C220.81 86.59, 213.06 93.69, 196.75 95.27 M220.56 71.45 C221.05 85.71, 210.41 93.9, 196.75 95.27 M196.75 95.27 C158.77 95.3, 116.48 95.21, 23.82 95.27 M196.75 95.27 C151.77 95.73, 105.1 95.39, 23.82 95.27 M23.82 95.27 C8.09 97.01, -1.6 86.27, 0 71.45 M23.82 95.27 C6.69 97.13, -1.41 85.29, 0 71.45 M0 71.45 C0.19 59.05, 0.6 44.44, 0 23.82 M0 71.45 C0.06 53.44, -0.92 36.28, 0 23.82 M0 23.82 C0.36 7.78, 8.38 -1.5, 23.82 0 M0 23.82 C-0.1 8.68, 5.78 -2.16, 23.82 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(839.5780334472656 285.265625) rotate(0 93.33993530273438 12.5)"><text x="93.33993530273438" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Gateway Controller</text></g><g stroke-linecap="round" transform="translate(939.5 12.625) rotate(0 81.77734375 41.41015625)"><path d="M20.71 0 C56.95 1.65, 89.18 -0.68, 142.85 0 C159.8 -0.58, 166.6 10.18, 163.55 20.71 C161.08 33.25, 165.55 40.16, 163.55 62.12 C166.23 78.86, 156.24 80.86, 142.85 82.82 C99.65 80.64, 52.44 83.77, 20.71 82.82 C7.49 80.52, 1.3 75.62, 0 62.12 C-0.76 50.89, 2.19 39.45, 0 20.71 C2.33 4.4, 3.71 -0.81, 20.71 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M20.71 0 C65.19 -0.08, 112.71 -1.26, 142.85 0 M20.71 0 C46.04 0.33, 70.7 0.37, 142.85 0 M142.85 0 C157.33 0.63, 162.82 8.21, 163.55 20.71 M142.85 0 C157.68 0.45, 161.53 7.71, 163.55 20.71 M163.55 20.71 C165.74 33.72, 162.01 49.31, 163.55 62.12 M163.55 20.71 C163.68 31.27, 163.54 43.83, 163.55 62.12 M163.55 62.12 C164.24 75.7, 157.52 81.56, 142.85 82.82 M163.55 62.12 C164.79 76.17, 156.97 81.05, 142.85 82.82 M142.85 82.82 C99.61 85.16, 56.9 82.6, 20.71 82.82 M142.85 82.82 C111.28 81.63, 80.2 81.85, 20.71 82.82 M20.71 82.82 C7.12 82.37, 0.01 77.24, 0 62.12 M20.71 82.82 C5.96 81.25, 0.02 77.13, 0 62.12 M0 62.12 C0.89 47.15, -0.73 31.99, 0 20.71 M0 62.12 C0.69 46.92, -0.55 31.39, 0 20.71 M0 20.71 C1.74 6.85, 8.29 1.3, 20.71 0 M0 20.71 C-0.27 8.52, 8.72 -1.06, 20.71 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(994.1373672485352 41.53515625) rotate(0 27.139976501464844 12.5)"><text x="27.139976501464844" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Client</text></g><g stroke-linecap="round"><g transform="translate(922.86328125 52.800949860671494) rotate(0 -105.361328125 -0.8692249303357471)"><path d="M0.05 -1.15 C-35.27 -1.48, -175.62 -1.12, -210.8 -1.08 M-1.38 0.86 C-36.97 0.11, -176.69 -2.25, -211.78 -2.85" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(922.86328125 52.800949860671494) rotate(0 -105.361328125 -0.8692249303357471)"><path d="M-188.15 -11 C-199.38 -7.88, -205.73 -5.01, -211.78 -2.85 M-188.15 -11 C-196.2 -7.3, -205.19 -5.52, -211.78 -2.85" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(922.86328125 52.800949860671494) rotate(0 -105.361328125 -0.8692249303357471)"><path d="M-188.44 6.1 C-199.68 2.44, -205.91 -1.47, -211.78 -2.85 M-188.44 6.1 C-196.43 3.45, -205.31 -1.13, -211.78 -2.85" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(769.3978710609954 17.177734375) rotate(0 51.191972689004615 12.5)"><text x="51.19197268900463" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Traffic</text></g><g stroke-linecap="round"><g transform="translate(928.5772506621181 219.29633228183508) rotate(188.5660498991342 -120.40162861425495 -46.92349377479326)"><path d="M0.36 0.29 C-18.72 -4.9, -73.42 -14.9, -113.8 -30.55 C-154.19 -46.2, -220.65 -83.14, -241.95 -93.61" stroke="#1e1e1e" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(928.5772506621181 219.29633228183508) rotate(188.5660498991342 -120.40162861425495 -46.92349377479326)"><path d="M-24.48 3.06 C-15.16 2.08, -6.74 -0.91, 0.36 0.29" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g><g transform="translate(928.5772506621181 219.29633228183508) rotate(188.5660498991342 -120.40162861425495 -46.92349377479326)"><path d="M-20.45 -13.56 C-12.49 -8.61, -5.51 -5.67, 0.36 0.29" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(808.2207168425398 138.22265625) rotate(0 65.25584565746021 12.5)"><text x="65.25584565746026" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Configures</text></g><g stroke-linecap="round"><g transform="translate(936.1958922859567 362.769287109375) rotate(0 -23.21419036734494 58.019165039062386)"><path d="M-1.13 -0.25 C-2.06 8.87, 1.28 36.06, -6.23 55.34 C-13.74 74.61, -39.48 105.14, -46.19 115.41" stroke="#1e1e1e" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(936.1958922859567 362.769287109375) rotate(0 -23.21419036734494 58.019165039062386)"><path d="M-39.18 91.41 C-41.21 95.6, -42.88 103.65, -46.19 115.41" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g><g transform="translate(936.1958922859567 362.769287109375) rotate(0 -23.21419036734494 58.019165039062386)"><path d="M-25.4 101.53 C-30.9 103.08, -35.99 108.61, -46.19 115.41" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(916.1386855925398 411.0198168925692) rotate(0 65.25584565746021 12.5)"><text x="65.25584565746026" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Watches</text></g><g stroke-linecap="round"><g transform="translate(588.5429687499998 351.429443359375) rotate(0 122.8481522518822 57.28979177205491)"><path d="M0.47 -0.11 C22.8 4.97, 94.27 11.32, 135.12 30.3 C175.96 49.28, 227.09 99.84, 245.55 113.78" stroke="#1e1e1e" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(588.5429687499998 351.429443359375) rotate(0 122.8481522518822 57.28979177205491)"><path d="M222.1 105.1 C231.12 108.37, 241.01 111.58, 245.55 113.78" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g><g transform="translate(588.5429687499998 351.429443359375) rotate(0 122.8481522518822 57.28979177205491)"><path d="M233.16 92.06 C237.82 100.5, 243.37 108.82, 245.55 113.78" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(548.2324355925398 380.9690356425692) rotate(0 65.25584565746027 12.5)"><text x="65.25584565746026" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Watches</text></g><g stroke-linecap="round"><g transform="translate(576.5078124999999 352.515380859375) rotate(0 -44.48890245947399 58.01171875)"><path d="M0.29 0.13 C-8.58 7.05, -38.57 21.75, -53.43 41.23 C-68.3 60.7, -83.15 104.69, -88.91 116.98" stroke="#1e1e1e" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(576.5078124999999 352.515380859375) rotate(0 -44.48890245947399 58.01171875)"><path d="M-87.94 91.99 C-88.07 99.24, -86.69 106.09, -88.91 116.98" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g><g transform="translate(576.5078124999999 352.515380859375) rotate(0 -44.48890245947399 58.01171875)"><path d="M-72.11 98.46 C-76.65 103.94, -79.69 108.97, -88.91 116.98" stroke="#1e1e1e" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g stroke-linecap="round" transform="translate(345.9375000000001 482.374755859375) rotate(0 192.640625 67.5)"><path d="M32 0 C124.8 2.14, 219.69 1.16, 353.28 0 C373.53 -2.23, 388.32 9.95, 385.28 32 C385.01 47.4, 383.1 64.23, 385.28 103 C383.05 124.97, 371.76 134.65, 353.28 135 C254.19 135.34, 159.26 135.32, 32 135 C12.11 132, 1.72 125.61, 0 103 C1.89 83.85, 1.87 72.43, 0 32 C-3.44 11.92, 9.2 -1.19, 32 0" stroke="none" stroke-width="0" fill="#b2f2bb"></path><path d="M32 0 C104.31 -1.26, 178.52 0.55, 353.28 0 M32 0 C102.8 -0.83, 174.05 -0.62, 353.28 0 M353.28 0 C376.58 -1.79, 386.27 10.59, 385.28 32 M353.28 0 C373.19 -0.61, 383.09 11.87, 385.28 32 M385.28 32 C384.58 50.05, 387.68 68.55, 385.28 103 M385.28 32 C385.16 60.8, 385.86 88.87, 385.28 103 M385.28 103 C386.65 124, 373.36 136.9, 353.28 135 M385.28 103 C383.65 122.77, 375.36 133.82, 353.28 135 M353.28 135 C263.61 135.48, 172.06 134.17, 32 135 M353.28 135 C287.69 133.75, 221.64 133.19, 32 135 M32 135 C11.51 134.85, 0.4 125.7, 0 103 M32 135 C8.6 136.46, 1.03 122.73, 0 103 M0 103 C-0.97 75.24, 1.04 47.9, 0 32 M0 103 C-0.29 85.46, 1.51 67.2, 0 32 M0 32 C1.75 11.96, 11.27 0.67, 32 0 M0 32 C0.96 9.77, 10.61 1.16, 32 0" stroke="#2f9e44" stroke-width="2" fill="none"></path></g><g transform="translate(350.9375000000001 499.874755859375) rotate(0 167.35987854003906 50)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">         InferenceObjective API</text><text x="0" y="42.62" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> Defines</text><text x="0" y="67.62" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"> - serving objectives for matching </text><text x="0" y="92.62" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">   requests</text></g><g stroke-linecap="round"><g transform="translate(466.70349253341556 319.4214301116765) rotate(0 -133.21484375 45.662109375)"><path d="M0.85 -1.12 C-25.83 1.76, -116.7 1.03, -161.23 16.39 C-205.76 31.75, -248.8 78.51, -266.33 91.04" stroke="#2f9e44" stroke-width="2.5" fill="none" stroke-dasharray="8 10"></path></g><g transform="translate(466.70349253341556 319.4214301116765) rotate(0 -133.21484375 45.662109375)"><path d="M-22.02 8.97 C-19.1 7.6, -11.91 4.8, 0.85 -1.12" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g><g transform="translate(466.70349253341556 319.4214301116765) rotate(0 -133.21484375 45.662109375)"><path d="M-23.16 -8.09 C-20.13 -5.95, -12.71 -5.23, 0.85 -1.12" stroke="#2f9e44" stroke-width="2.5" fill="none"></path></g></g><mask></mask><g transform="translate(277.3282506200807 346.804443359375) rotate(0 72.95104625491925 25)"><text x="72.95104625491925" y="17.5" font-family="Comic Shanns, monospace, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Observability</text><text x="72.95104625491925" y="42.5" font-family="Comic Shanns, monospace, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Protocol</text></g><g stroke-linecap="round" transform="translate(10 400.050537109375) rotate(0 85.671875 55)"><path d="M27.5 0 C57.96 0.23, 92.07 -2.16, 143.84 0 C161.98 -1.62, 171.53 10.07, 171.34 27.5 C172.01 46.69, 172.38 68.01, 171.34 82.5 C169.13 104.28, 159.03 113.05, 143.84 110 C96.78 106.99, 54.06 111.19, 27.5 110 C8.1 113.16, -3.25 101.52, 0 82.5 C3.07 64.43, 1.44 46.39, 0 27.5 C-1.67 6.06, 12.67 3.19, 27.5 0" stroke="none" stroke-width="0" fill="#ffec99"></path><path d="M27.5 0 C58.62 0.1, 86.75 -0.75, 143.84 0 M27.5 0 C66.17 1.24, 103.86 0.14, 143.84 0 M143.84 0 C160.73 1.75, 169.79 10.1, 171.34 27.5 M143.84 0 C162.38 2.15, 171.96 8.78, 171.34 27.5 M171.34 27.5 C170.44 50.01, 172.38 71.02, 171.34 82.5 M171.34 27.5 C172.51 49.03, 171.57 70.72, 171.34 82.5 M171.34 82.5 C171.08 100.74, 161.79 108.79, 143.84 110 M171.34 82.5 C169.18 99.21, 163.59 112.09, 143.84 110 M143.84 110 C100.17 110.08, 56.23 110.56, 27.5 110 M143.84 110 C97.23 108.17, 51.87 108.41, 27.5 110 M27.5 110 C8.79 111.81, -1.3 100.22, 0 82.5 M27.5 110 C11.27 110.65, -0.82 102.29, 0 82.5 M0 82.5 C1.49 66.6, -0.48 54.73, 0 27.5 M0 82.5 C-0.44 69.52, 0.7 54.3, 0 27.5 M0 27.5 C-1.19 9.05, 11.1 -1.12, 27.5 0 M0 27.5 C-1.28 8.1, 10.63 1.93, 27.5 0" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(33.09192307293415 430.050537109375) rotate(0 62.57995192706585 25)"><text x="62.57995192706585" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Observability</text><text x="62.57995192706585" y="42.62" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Dashboards</text></g></svg>
\ No newline at end of file
diff --git a/docs/proposals/002-api-proposal/README.md b/docs/proposals/002-api-proposal/README.md
index b8bf14b..e886008 100644
--- a/docs/proposals/002-api-proposal/README.md
+++ b/docs/proposals/002-api-proposal/README.md
@@ -2,7 +2,11 @@
 # Gateway API Inference Extension
 
 ## Proposal Status
- ***Draft***
+ ***Implemented/Obsolete*** 
+ - Refer to [the InferencePool v1 API review](https://github.com/kubernetes-sigs/gateway-api-inference-extension/pull/1173) for the InferencePool modifications
+ - Refer to [the InferenceModel evolution proposal](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals/1199-inferencemodel-api-evolution) for the InferenceModel modifications
+ - Refer to the `/api/` & `/apix/` directories for the current status
+
 
 ## Table of Contents
 
diff --git a/docs/proposals/003-model-server-protocol/README.md b/docs/proposals/003-model-server-protocol/README.md
index 4b27743..65e440a 100644
--- a/docs/proposals/003-model-server-protocol/README.md
+++ b/docs/proposals/003-model-server-protocol/README.md
@@ -2,6 +2,12 @@
 
 This is the protocol between the EPP and the model servers.
 
+## Proposal status
+***Partially implemented***
+
+Notes
+- With the creation of the [pluggable architecture](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals/0683-epp-architecture-proposal) this protocol can, by definition, not be as strict
+
 ### Inference API Protocol
 
 The model server MUST implement OpenAI’s [Completions](https://platform.openai.com/docs/api-reference/completions)
diff --git a/docs/proposals/004-endpoint-picker-protocol/README.md b/docs/proposals/004-endpoint-picker-protocol/README.md
index 18cb10d..919bb63 100644
--- a/docs/proposals/004-endpoint-picker-protocol/README.md
+++ b/docs/proposals/004-endpoint-picker-protocol/README.md
@@ -1,5 +1,10 @@
 # Endpoint Picker Protocol
 
+## Proposal Status
+***Implemented***
+
+# Proposal
+
 The Endpoint Picker, or EPP, is a core component of the inference extension. Ultimately it's
 responsible for picking an endpoint from the `InferencePool`. A reference implementation can be
 found [here](../../../pkg/epp/).
@@ -9,6 +14,15 @@ This doc defines the protocol between the EPP and the proxy (e.g, Envoy).
 The EPP MUST implement the Envoy
 [external processing service](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/ext_proc.proto) protocol.
 
+## Version History
+
+| Version  | Date       | Changes                                          |
+|----------|------------|--------------------------------------------------|
+| v1.0.0   | 2025-07-29 | Added status metadata field for picked endpoints |
+| v0.4.0   | 2025-06-03 | Added support for multiple fallback endpoints    |
+| v0.3.0   | 2025-03-14 | Added subsetting and fallback support            |
+| v0.2.0   | 2025-02-22 | Initial protocol definition                      |
+
 ## Endpoint Subset
 
 [REQUEST: Data Plane -> EPP]
diff --git a/docs/proposals/006-scheduler/README.md b/docs/proposals/006-scheduler/README.md
index 77fc4c2..21aa31f 100644
--- a/docs/proposals/006-scheduler/README.md
+++ b/docs/proposals/006-scheduler/README.md
@@ -3,7 +3,7 @@
 Authors: @kfswain, @smarterclayton
 
 ## Proposal Status
- ***Draft***
+ ***Implemented***
 
 ## Table of Contents
 
diff --git a/docs/proposals/0602-prefix-cache-aware-routing-proposal/README.md b/docs/proposals/0602-prefix-cache-aware-routing-proposal/README.md
index 468e3be..7388d91 100644
--- a/docs/proposals/0602-prefix-cache-aware-routing-proposal/README.md
+++ b/docs/proposals/0602-prefix-cache-aware-routing-proposal/README.md
@@ -1,5 +1,10 @@
 # Prefix Cache Aware Request Scheduling
 
+## Proposal Status
+***Implemented***
+
+# Proposal
+
 ## Overview
 
 Prefix caching is a well-known technique in LLM inference to save duplicate tensor computation for prompts with the same prefix tokens, and is available in many model servers or model as a service providers. Leveraging prefix caching can significantly boost system performance, especially the time to first token (TTFT). Given that EPP has a global view of requests and model servers in the `InferencePool`, it can schedule requests intelligently to maximize the global prefix cache hit rate.
diff --git a/docs/proposals/0683-epp-architecture-proposal/README.md b/docs/proposals/0683-epp-architecture-proposal/README.md
index 7bd688c..c788e45 100644
--- a/docs/proposals/0683-epp-architecture-proposal/README.md
+++ b/docs/proposals/0683-epp-architecture-proposal/README.md
@@ -2,7 +2,7 @@
 
 Author(s): @kfswain
 ## Proposal Status
- ***Draft***
+ ***Implemented***
 
 ## Summary
 
diff --git a/docs/proposals/0845-scheduler-architecture-proposal/README.md b/docs/proposals/0845-scheduler-architecture-proposal/README.md
index 4141ce6..8c3e5d9 100644
--- a/docs/proposals/0845-scheduler-architecture-proposal/README.md
+++ b/docs/proposals/0845-scheduler-architecture-proposal/README.md
@@ -2,7 +2,7 @@
 
 Author(s): @kfswain, @ahg-g, @nirrozenbaum
 ## Proposal Status
- ***Draft***
+ ***Implemented***
 
 ## Summary
 The Scheduling Subsystem is a framework used to implement scheduling algorithms. High level definition [here](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals/006-scheduler) & EPP Architecture [here](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals/0683-epp-architecture-proposal).
diff --git a/docs/proposals/1023-data-layer-architecture/README.md b/docs/proposals/1023-data-layer-architecture/README.md
index e392643..5af12ab 100644
--- a/docs/proposals/1023-data-layer-architecture/README.md
+++ b/docs/proposals/1023-data-layer-architecture/README.md
@@ -4,7 +4,7 @@ Author(s): @elevran @nirrozenbaum
 
 ## Proposal Status
 
-***Draft***
+***Accepted***
 
 ## Summary
 
diff --git a/docs/proposals/1199-inferencemodel-api-evolution/README.md b/docs/proposals/1199-inferencemodel-api-evolution/README.md
index 1ad687d..5478fd4 100644
--- a/docs/proposals/1199-inferencemodel-api-evolution/README.md
+++ b/docs/proposals/1199-inferencemodel-api-evolution/README.md
@@ -2,7 +2,11 @@
 
 Author(s): @kfswain, @ahg-g, @lukeavandrie
 ## Proposal Status
- ***Draft***
+ ***Implemented***
+ 
+ Note
+ - Phase 1 is complete
+ - Phase 2 is still WIP
 
 ## Summary
 Multiple docs have discussed the restructuring of the InferenceModel API. This [doc](https://docs.google.com/document/d/1x6aI9pbTF5oOsaEQYc9n4pBBY3_AuEY2X51VKxmBSnU/edit?tab=t.0#heading=h.towq7jyczzgo) proposes an InferenceSchedulingObjective CRD, and this [doc](https://docs.google.com/document/d/1G-CQ17CM4j1vNE3T6u9uP2q-m6jK14ANPCwTfJ2qLS4/edit?tab=t.0) builds upon the previous document to solidify the requirement for the new iteration of the InferenceModel API to continue to solve the identity problem. Both these documents were useful in continuing to gather feedback & iterate on a proper solution. 
diff --git a/docs/proposals/1374-multi-cluster-inference/README.md b/docs/proposals/1374-multi-cluster-inference/README.md
new file mode 100644
index 0000000..321b0d2
--- /dev/null
+++ b/docs/proposals/1374-multi-cluster-inference/README.md
@@ -0,0 +1,493 @@
+# Multi-Cluster InferencePools
+
+Author(s): @danehans, @bexxmodd, @robscott
+
+## Proposal Status
+
+ ***Draft***
+
+## Summary
+
+An Inference Gateway (IG) provides efficient routing to LLM workloads in Kubernetes by sending requests to an Endpoint Picker (EPP) associated with
+an [InferencePool](https://gateway-api-inference-extension.sigs.k8s.io/api-types/inferencepool/) and routing the request to a backend model server
+based on the EPP-provided endpoint. Although other multi-cluster inference approaches may exist, this proposal extends the current model to support
+multi-cluster routing so capacity in one cluster can serve traffic originating in another cluster or outside the clusters.
+
+### Why Multi-Cluster?
+
+GPU capacity is scarce and fragmented. Many users operate multiple clusters across regions and providers. A single cluster rarely satisfies peak or
+sustained demand, so a prescribed approach is required to share GPU capacity across clusters by:
+
+- Exporting an InferencePool from a source (“exporting”) cluster.
+- Importing the exported InferencePool into one or more destination (“importing”) clusters with enough detail for IGs to route requests to the associated
+  remote model server Pods.
+
+### Goals
+
+- Enable IGs to route to a group of common model server Pods, e.g. InferencePools, that exist in different clusters.
+- Align the UX with familiar [Multi-Cluster Services (MCS)](https://multicluster.sigs.k8s.io/concepts/multicluster-services-api/) concepts (export/import).
+- Keep the API simple and implementation-agnostic.
+
+### Non-Goals
+
+- Managing DNS or automatic naming.
+- Over-specifying implementation details to satisfy a single approach to Multi-Cluster InferencePools.
+
+## Design Proposal
+
+The Multi-Cluster InferencePools (MCIP) model will largely follow the Multi-Cluster Services (MCS) model, with a few key differences:
+
+- DNS and ClusterIP resolution will be omitted, e.g. ClusterSetIP.
+- A separate export resource will be avoided, e.g. ServiceExport, by inlining the concept within InferencePool.
+
+An InferencePoolImport resource is introduced that is meant to be fully managed by a controller. This resource provides the information
+required for IGs to route LLM requests to model server endpoints of an InferencePool in remote clusters. How the IG routes the request to the remote
+cluster is implementation-specific.
+
+### Routing Modes
+
+An implementation must support at least one of the following routing modes:
+
+- Endpoint Mode: An IG of an importing cluster routes to endpoints selected by the EPP of the exported InferencePool. Pod and Service network connectivity
+  MUST exist between cluster members.
+- Parent Mode: An IG of an importing cluster routes to parents, e.g. Gateways, of the exported InferencePool. Parent connectivity MUST exist between cluster
+  members.
+
+### Sync Topology (Implementation-Specific)
+
+An implementation must support at least one of the following distribution topologies. The API does not change between them (same export annotation and InferencePoolImport).
+
+1. **Hub/Spoke**
+   - A hub controller has visibility into member clusters.
+   - It watches exported InferencePools and creates/updates the corresponding InferencePoolImport (same namespace/name) in each member cluster.
+   - Typical when a central control plane has K8s API server access for each member cluster.
+   - Consider [KEP-5339-style](https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/5339-clusterprofile-plugin-credentials) pluggable credential issuance to avoid hub-stored long-lived secrets.
+
+2. **Push/Pull**
+   - A cluster-local controller watches exported InferencePools and publishes export state to a central hub.
+   - A cluster-local controller watches the central hub and CRUDs the local InferencePoolImport.
+   - Typical when you want no hub-stored member credentials, looser coupling, and fleet-scale fan-out.
+
+### Workflow
+
+1. **Export an InferencePool:** An [Inference Platform Owner](https://gateway-api-inference-extension.sigs.k8s.io/concepts/roles-and-personas/)
+   exports an InferencePool by annotating it.
+2. **Distribution (topology-dependent, API-agnostic):**
+   - **Hub/Spoke:** A central hub controller watches exported InferencePools and mirrors a same-name/namespace InferencePoolImport into each member cluster, updating `status.controllers[]` to reflect the managing controller, exporting clusters, etc..
+   - **Push/Pull:** A cluster-local controller watches exported InferencePools and publishes export records to a central hub. In each member cluster, a controller watches the hub and CRUDs the local InferencePoolImport (same name/namespace) and maintains `status.controllers[]`.
+3. **Importing Controller (common):**
+   - Watches local InferencePoolImport and:
+     - Programs the IG dataplane based on the supported routing mode.
+     - If this controller differs from the Exporting Controller, populate `status.controllers[]`.
+     - Manages `status.controllers[].parentRefs` with the Group, Kind, and Name of the local parent resource, e.g. Gateway, of the InferencePoolImport.
+4. **Data Path:**
+   The data path is dependent on the export mode selected by the implementation.
+   - Endpoint Mode: Client → local IG → (make scheduling decision) → local/remote EPP → selected model server endpoint → response.
+   - Parent Mode: Client → local IG → (make scheduling decision) → local EPP/remote parent → remote EPP → selected model server endpoint → response.
+
+### InferencePoolImport Naming
+
+The exporting controller will create an InferencePoolImport resource using the exported InferencePool namespace and name. A cluster name entry in
+`status.controllers[]` is added for each cluster that exports an InferencePool with the same ns/name.
+
+**Note:** EPP ns/name sameness is not required.
+
+### InferencePool Selection
+
+InferencePool selection is implementation-specific. The following are examples of how an IG may select one exported InferencePool over another:
+
+- **Metrics-based:** Scrape EPP-exposed metrics (e.g., ready pods) to bias InferencePool choice.
+- **Active-Passive:** Basic EPP readiness checks (gRPC health).
+
+**Note:** When an exported InferencePool is selected by an IG, standard EPP semantics are used to select endpoints of that pool.
+
+### API Changes
+
+#### InferencePool Annotation
+
+The following annotation is being proposed to indicate the desire to export the InferencePool to member clusters of a ClusterSet.
+
+The `inference.networking.x-k8s.io/export` annotation key indicates a desire to export the InferencePool:
+
+```yaml
+inference.networking.x-k8s.io/export: "<value>"
+```
+
+Supported Values:
+
+- `ClusterSet` – export to all members of the current [ClusterSet](https://multicluster.sigs.k8s.io/api-types/cluster-set/).
+
+**Note:** Additional annotations, e.g. region/domain scoping, filter clusters in the ClusterSet, routing mode configuration, etc. and
+potentially adding an InferencePoolExport resource may be considered in the future.
+
+#### InferencePool Status
+
+An implementation MUST set a parent status entry with a parentRef of kind `InferencePoolImport` and the ns/name of the exported InferencePool.
+This informs the user that the request to export the InferencePool has been recognized by the implementation, along with the implementation's
+unique `ControllerName`.  `ControllerName` is a domain/path string that indicates the name of the controller that wrote the status entry.
+
+An `Exported` parent condition type is being added to surface status of the exported InferencePool. An implementation MUST set
+this status condition to `True` when the annotated InferencePool has been exported to all member clusters of the ClusterSet and `False`
+for all other reasons. When the export annotation is removed from the InferencePool, an implementation MUST remove this condition type.
+
+#### InferencePoolImport
+
+A cluster-local, controller-managed resource that represents an imported InferencePool. It primarily communicates a relationship between an exported
+InferencePool and the exporting cluster name. It is not user-authored; status carries the effective import. Inference Platform Owners can reference
+the InferencePoolImport, even if the local cluster does not have an InferencePool. In the context of Gateway API, it means that an HTTPRoute can be
+configured to reference an InferencePoolImport to route matching requests to remote InferencePool endpoints. This API will be used almost exclusively
+for tracking endpoints, but unlike MCS, we actually have two distinct sets of endpoints to track:
+
+1. Endpoint Picker Extensions (EPPs)
+2. InferencePool parents, e.g. Gateways
+
+Key ideas:
+
+- Map exported InferencePool to exporting controller and cluster.
+- Name/namespace sameness with the exported InferencePool (avoids extra indirection).
+- Conditions: Surface a controller-level status condition to indicate that the InferencePoolImport is ready to be used.
+- Conditions: Surface parent-level status conditions to indicate that the InferencePoolImport is referenced by a parent, e.g. Gateway.
+
+See the full Go type below for additional details.
+
+## Controller Responsibilities
+
+**Export Controller:**
+
+- Discover exported InferencePools.
+- For each ClusterSet member cluster, CRUD InferencePoolImport (mirrored namespace/name).
+- Populate the exported InferencePool with status to indicate a unique name of the managing controller and an `Exported`  condition that
+  indicates the status of the exported pool.
+- Populate an InferencePoolImport `status.controllers[]` entry with the managing controller name, cluster, and status conditions associated
+  with the exported InferencePool.
+
+**Import Controller:**
+
+- Watch InferencePoolImports.
+- Program the IG data plane to route matching requests based on the supported routing mode.
+- Manage InferencePoolImport `status.controllers[].parentRefs` with a cluster-local parentRef, e.g. Gateway, when the InferencePoolImport
+  is referenced by a managed HTTProute.
+
+## Examples
+
+### Exporting Cluster (Cluster A) Manifests
+
+In this example, Cluster A exports the InferencePool to all clusters in the ClusterSet. This will
+cause the exporting controller to create an InferencePoolImport resource in all clusters.
+
+```yaml
+apiVersion: inference.networking.k8s.io/v1
+kind: InferencePool
+metadata:
+  name: llm-pool
+  namespace: example
+  annotations:
+    inference.networking.x-k8s.io/export: "ClusterSet" # Export the pool to all clusters in the ClusterSet
+spec:
+  endpointPickerRef:
+    name: epp
+    portNumber: 9002
+  selector:
+    matchLabels:
+      app: my-model
+  targetPorts:
+  - number: 8080
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: epp
+  namespace: example
+spec:
+  selector:
+    app: epp
+  ports:
+  - name: ext-proc
+    port: 9002
+    targetPort: 9002
+    appProtocol: http2
+  type: LoadBalancer # EPP exposed via LoadBalancer
+```
+
+### Importing Cluster (Cluster B) Manifests
+
+In this example, the Inference Platform Owner has configured an HTTPRoute to route to endpoints of the Cluster A InferencePool
+by referencing the InferencePoolImport as a `backendRef`. The parent IG(s) of the HTTPRoute are responsible for routing to the
+endpoints selected by the exported InferencePool's EPP.
+
+The InferencePoolImport is controller-managed; shown here only to illustrate the expected status shape.
+
+```yaml
+apiVersion: inference.networking.x-k8s.io/v1alpha1
+kind: InferencePoolImport
+metadata:
+  name: llm-pool      # mirrors exporting InferencePool name
+  namespace: example  # mirrors exporting InferencePool namespace
+status:
+  controllers:
+  - controllerName: example.com/mcip-controller
+    type: MultiCluster
+    exportingClusters:
+    - name: cluster-a
+  - controllerName: example.com/ig-controller
+    type: GatewayClass
+    parents:
+    - parentRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: inf-gw # Cluster-local parent, e.g. gateway
+      conditions:
+      - type: Accepted
+        status: "True"
+---
+# Route in the importing cluster that targets the imported pool
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: HTTPRoute
+metadata:
+  name: llm-route
+  namespace: example
+spec:
+  parentRefs:
+  - name: inf-gw
+  hostnames:
+  - my.model.com
+  rules:
+  - matches:
+    - path:
+        type: PathPrefix
+        value: /completions
+    backendRefs:
+    - group: inference.networking.x-k8s.io
+      kind: InferencePoolImport
+      name: llm-pool
+```
+
+An implementation MUST conform to Gateway API specifications, including when the HTTPRoute contains InferencePool and InferencePoolImport `backendRefs`,
+e.g. `weight`-based load balancing. In the following example, traffic MUST be split equally between Cluster A and B InferencePool endpoints when
+using the following `backendRefs`:
+
+```yaml
+    backendRefs:
+    - group: inference.networking.k8s.io
+      kind: InferencePool
+      name: llm-pool
+      weight: 50
+    - group: inference.networking.x-k8s.io
+      kind: InferencePoolImport
+      name: llm-pool
+      weight: 50
+```
+
+**Note:** The above example does not export the local "llm-pool" InferencePool. If this InferencePool was exported, it would be included in
+the example InferencePoolImport and the implementation would be responsible for balancing the traffic between the two pools.
+
+### Go Types
+
+The following Go types define the InferencePoolImport API being introduced by this proposal. Note that a separate Pull Request will be used
+to finalize and merge all Go types into the repository.
+
+```go
+package v1alpha1
+
+import (
+    corev1 "k8s.io/api/core/v1"
+    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+    v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+)
+
+// +kubebuilder:object:root=true
+// +kubebuilder:resource:scope=Namespaced,shortName=ipimp
+// +kubebuilder:subresource:status
+//
+// InferencePoolImport represents an imported InferencePool from another cluster.
+// This resource is controller-managed; users typically do not author it directly.
+type InferencePoolImport struct {
+    metav1.TypeMeta   `json:",inline"`
+    metav1.ObjectMeta `json:"metadata,omitempty"`
+
+    // Spec defines the desired state of the InferencePoolImport.
+    Spec InferencePoolImportSpec `json:"spec,omitempty"`
+
+    // Status defines the current state of the InferencePoolImport.
+    Status InferencePoolImportStatus `json:"status,omitempty"`
+}
+
+// Unused but defined for potential future use.
+type InferencePoolImportSpec struct{}
+
+type InferencePoolImportStatus struct {
+    // Controllers is a list of controllers that are responsible for managing this InferencePoolImport.
+    //
+    // +kubebuilder:validation:Required
+    Controllers []ImportController `json:"controllers"`
+}
+
+// ImportController defines a controller that is responsible for managing this InferencePoolImport.
+type ImportController struct {
+    // Name is a domain/path string that indicates the name of the controller that manages this
+    // InferencePoolImport. This corresponds to the GatewayClass controllerName field when the
+    // controller will manage parents of type "Gateway". Otherwise, the name is implementation-specific.
+    //
+    // Example: "example.net/import-controller".
+    //
+    // The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are valid Kubernetes
+    // names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+    //
+    // A controller MUST populate this field when writing status and ensure that entries to status
+    // populated with their controller name are removed when they are no longer necessary.
+    //
+    // +required
+    Name ControllerName `json:"name"`
+
+    // ExportingClusters is a list of clusters that exported the InferencePool associated with this
+    // InferencePoolImport. Required when the controller is responsible for CRUD'ing the InferencePoolImport
+    // from the exported InferencePool(s).
+    //
+    // +optional
+    ExportingClusters []ExportingCluster `json:"exportingClusters"`
+
+    // Parents is a list of parent resources, typically Gateways, that are associated with the
+    // InferencePoolImport, and the status of the InferencePoolImport with respect to each parent.
+    //
+    // Required when the controller manages the InferencePoolImport as an HTTPRoute backendRef. The controller
+    // must add an entry for each parent it manages and remove the parent entry when the controller no longer
+    // considers the InferencePoolImport to be associated with that parent.
+    //
+    // +optional
+    // +listType=atomic
+    Parents []v1.ParentStatus `json:"parents,omitempty"`
+
+    // Conditions track the state of the InferencePoolImport.
+    //
+    // Known condition types are:
+    //
+    //  * "Accepted"
+    //
+    // +optional
+    // +listType=map
+    // +listMapKey=type
+    // +kubebuilder:validation:MaxItems=8
+    Conditions []metav1.Condition `json:"conditions,omitempty"`
+}
+
+// ControllerName is the name of a controller that manages a resource. It must be a domain prefixed path.
+//
+// Valid values include:
+//
+//  * "example.com/bar"
+//
+// Invalid values include:
+//
+//  * "example.com" - must include path
+//  * "foo.example.com" - must include path
+//
+// +kubebuilder:validation:MinLength=1
+// +kubebuilder:validation:MaxLength=253
+// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$`
+type ControllerName string
+
+// ExportingCluster defines a cluster that exported the InferencePool associated to this InferencePoolImport.
+type ExportingCluster struct {
+    // Name of the exporting cluster (must be unique within the list). 
+    //
+    // +kubebuilder:validation:Required
+    Name string `json:"name"`
+}
+
+// +kubebuilder:object:root=true
+type InferencePoolImportList struct {
+    metav1.TypeMeta `json:",inline"`
+    metav1.ListMeta `json:"metadata,omitempty"`
+    Items           []InferencePoolImport `json:"items"`
+}
+```
+
+### Failure Mode
+
+EPP failure modes continue to work as-is and are independent of MCIP.
+
+#### EPP Selection
+
+Since an IG decides which EPP to use for endpoint selection when multiple InferencePool/InferencePoolImport `backendRefs` exist,
+an implementation MAY use EPP metrics and/or health data to make a load-balancing decision.
+
+## Alternatives
+
+### Option 1: Reuse MCS API for EPP
+
+Reuse MCS to export EPP Services. This approach provides simple infra, but may be confusing to users (you “export EPPs” not pools) and
+requires a separate MCS parent export for parent-based inter-cluster routing.
+
+**Pros**:
+
+- Reuses existing MCS infrastructure.
+- Relatively simple to implement.
+
+**Cons**:
+
+- Referencing InferencePools in other clusters requires you to create an InferencePool locally.
+- In this model, you don’t actually choose to export an InferencePool, you export the EPP or InferencePool parent(s) service, that could lead to confusion.
+- InferencePool is meant to be a replacement for a Service so it may seem counterintuitive for a user to create a Service to achieve multi-cluster inference.
+
+## Option 2: New MCS API
+
+One of the key pain points we’re seeing here is that the current iteration of the MCS API requires a tight coupling between name/namespace and kind, with Service being the only kind of backend supported right now. This goes against the broader SIG-Network direction of introducing more focused kinds of backends (like InferencePool). To address this, we could create a resource that has an `exportRef` that allows for exporting different types of resources.
+
+While we were at it, we could combine the separate `export` and `import` resources that exist today, with `export` acting as the (optional) spec of this new resource, and `import` acting as `status` of the resource. Instead of `import` resources being automatically created, users would create them wherever they wanted to reference or export something to a MultiClusterService.
+
+Here’s a very rough example:
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: MultiClusterService
+metadata:
+  name: epp
+  namespace: example
+spec:
+  exportRef:
+    group: v1
+    kind: Service
+    name: epp
+    scope: ClusterSet
+status:
+  conditions:
+  - type: Accepted
+    status: "True"
+    message: "MultiClusterService has been accepted"
+    lastTransitionTime: "2025-03-30T01:33:51Z"
+  targetCount: 1
+  ports:
+  - protocol: TCP
+    appProtocol: HTTP
+    port: 8080
+```
+
+### Open Questions
+
+#### EPP Discovery
+
+- Should EPP Deployment/Pod discovery be standardized (labels/port names) for health/metrics auto-discovery?
+
+#### Security
+
+- Provide a standard way to bootstrap mTLS between importing IG and exported EPP/parents, e.g. use BackendTLSPolicy?
+
+#### Ownership and Lifecycle
+
+- Garbage collection when export is withdrawn (delete import?) and how to drain traffic safely. See [this comment](https://github.com/kubernetes-sigs/gateway-api-inference-extension/pull/1374#discussion_r2357523781) for additional context.
+
+### Prior Art
+
+- [GEP-1748: Gateway API Interaction with Multi-Cluster Services](https://gateway-api.sigs.k8s.io/geps/gep-1748/)
+- [Envoy Gateway with Multi-Cluster Services](https://gateway.envoyproxy.io/latest/tasks/traffic/multicluster-service/)
+- [Multi-Cluster Service API](https://multicluster.sigs.k8s.io/concepts/multicluster-services-api/)
+
+### References
+
+- [Initial Multi-Cluster Inference Design Doc](https://docs.google.com/document/d/1QGvG9ToaJ72vlCBdJe--hmrmLtgOV_ptJi9D58QMD2w/edit?tab=t.0#heading=h.q6xiq2fzcaia)
+
+### Notes for reviewers
+
+- The InferencePoolImport CRD is intentionally status-only to keep the UX simple and controller-driven.
+- The InferencePool namespace sameness simplifies identity and lets HTTPRoute authors reference imports without new indirection.
diff --git a/docs/scheduler-flowchart.png b/docs/scheduler-flowchart.png
deleted file mode 100644
index 4459ef1..0000000
Binary files a/docs/scheduler-flowchart.png and /dev/null differ
diff --git a/go.mod b/go.mod
index 619d8df..db34737 100644
--- a/go.mod
+++ b/go.mod
@@ -5,34 +5,35 @@ go 1.24.0
 require (
 	github.com/cespare/xxhash/v2 v2.3.0
 	github.com/elastic/crd-ref-docs v0.2.0
-	github.com/envoyproxy/go-control-plane/envoy v1.32.4
+	github.com/envoyproxy/go-control-plane/envoy v1.35.0
 	github.com/go-logr/logr v1.4.3
 	github.com/google/go-cmp v0.7.0
 	github.com/google/uuid v1.6.0
 	github.com/hashicorp/golang-lru/v2 v2.0.7
-	github.com/onsi/ginkgo/v2 v2.23.4
-	github.com/onsi/gomega v1.38.0
-	github.com/prometheus/client_golang v1.23.0
+	github.com/onsi/ginkgo/v2 v2.25.3
+	github.com/onsi/gomega v1.38.2
+	github.com/prometheus/client_golang v1.23.2
 	github.com/prometheus/client_model v0.6.2
-	github.com/prometheus/common v0.65.0
-	github.com/prometheus/prometheus v0.305.0
-	github.com/stretchr/testify v1.10.0
+	github.com/prometheus/common v0.66.1
+	github.com/prometheus/prometheus v0.306.0
+	github.com/stretchr/testify v1.11.1
 	go.uber.org/multierr v1.11.0
 	go.uber.org/zap v1.27.0
-	golang.org/x/sync v0.16.0
-	google.golang.org/grpc v1.74.2
-	google.golang.org/protobuf v1.36.7
-	k8s.io/api v0.33.3
-	k8s.io/apiextensions-apiserver v0.33.3
-	k8s.io/apimachinery v0.33.3
-	k8s.io/client-go v0.33.3
-	k8s.io/code-generator v0.33.3
-	k8s.io/component-base v0.33.3
-	k8s.io/utils v0.0.0-20241210054802-24370beab758
-	sigs.k8s.io/controller-runtime v0.21.0
-	sigs.k8s.io/controller-tools v0.18.0
-	sigs.k8s.io/gateway-api v1.3.0
-	sigs.k8s.io/structured-merge-diff/v4 v4.7.0
+	golang.org/x/sync v0.17.0
+	google.golang.org/grpc v1.76.0
+	google.golang.org/protobuf v1.36.10
+	k8s.io/api v0.34.1
+	k8s.io/apiextensions-apiserver v0.34.1
+	k8s.io/apimachinery v0.34.1
+	k8s.io/client-go v0.34.1
+	k8s.io/code-generator v0.34.1
+	k8s.io/component-base v0.34.1
+	k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d
+	sigs.k8s.io/controller-runtime v0.22.1
+	// Update the CONTROLLER_TOOLS_VERSION in Makefile when bumping controller-tools.
+	sigs.k8s.io/controller-tools v0.19.0
+	sigs.k8s.io/gateway-api v1.4.0
+	sigs.k8s.io/structured-merge-diff/v6 v6.3.0
 	sigs.k8s.io/yaml v1.6.0
 )
 
@@ -40,6 +41,7 @@ require (
 	cel.dev/expr v0.24.0 // indirect
 	github.com/Masterminds/goutils v1.1.1 // indirect
 	github.com/Masterminds/semver v1.5.0 // indirect
+	github.com/Masterminds/semver/v3 v3.4.0 // indirect
 	github.com/Masterminds/sprig v2.22.0+incompatible // indirect
 	github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
@@ -48,24 +50,24 @@ require (
 	github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/dennwc/varint v1.0.0 // indirect
-	github.com/emicklei/go-restful/v3 v3.12.0 // indirect
+	github.com/emicklei/go-restful/v3 v3.13.0 // indirect
 	github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
 	github.com/evanphx/json-patch/v5 v5.9.11 // indirect
 	github.com/felixge/httpsnoop v1.0.4 // indirect
-	github.com/fsnotify/fsnotify v1.8.0 // indirect
-	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
+	github.com/fsnotify/fsnotify v1.9.0 // indirect
+	github.com/fxamacker/cbor/v2 v2.9.0 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-logr/zapr v1.3.0 // indirect
-	github.com/go-openapi/jsonpointer v0.21.0 // indirect
+	github.com/go-openapi/jsonpointer v0.21.2 // indirect
 	github.com/go-openapi/jsonreference v0.21.0 // indirect
-	github.com/go-openapi/swag v0.23.0 // indirect
+	github.com/go-openapi/swag v0.23.1 // indirect
 	github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
 	github.com/gobuffalo/flect v1.0.3 // indirect
 	github.com/goccy/go-yaml v1.18.0 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/google/btree v1.1.3 // indirect
-	github.com/google/cel-go v0.23.2 // indirect
-	github.com/google/gnostic-models v0.6.9 // indirect
+	github.com/google/cel-go v0.26.0 // indirect
+	github.com/google/gnostic-models v0.7.0 // indirect
 	github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect
 	github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
 	github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
@@ -76,57 +78,56 @@ require (
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/kylelemons/godebug v1.1.0 // indirect
-	github.com/mailru/easyjson v0.7.7 // indirect
+	github.com/mailru/easyjson v0.9.0 // indirect
 	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/reflectwalk v1.0.2 // indirect
 	github.com/moby/spdystream v0.5.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
-	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
-	github.com/pkg/errors v0.9.1 // indirect
 	github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
-	github.com/prometheus/procfs v0.16.1 // indirect
+	github.com/prometheus/procfs v0.17.0 // indirect
 	github.com/spf13/cobra v1.9.1 // indirect
-	github.com/spf13/pflag v1.0.6 // indirect
+	github.com/spf13/pflag v1.0.7 // indirect
 	github.com/stoewer/go-strcase v1.3.0 // indirect
 	github.com/x448/float16 v0.8.4 // indirect
 	go.opentelemetry.io/auto/sdk v1.1.0 // indirect
 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
-	go.opentelemetry.io/otel v1.36.0 // indirect
+	go.opentelemetry.io/otel v1.37.0 // indirect
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 // indirect
-	go.opentelemetry.io/otel/metric v1.36.0 // indirect
-	go.opentelemetry.io/otel/sdk v1.36.0 // indirect
-	go.opentelemetry.io/otel/trace v1.36.0 // indirect
-	go.opentelemetry.io/proto/otlp v1.6.0 // indirect
+	go.opentelemetry.io/otel/metric v1.37.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.37.0 // indirect
+	go.opentelemetry.io/otel/trace v1.37.0 // indirect
+	go.opentelemetry.io/proto/otlp v1.7.0 // indirect
 	go.uber.org/atomic v1.11.0 // indirect
 	go.uber.org/automaxprocs v1.6.0 // indirect
 	go.yaml.in/yaml/v2 v2.4.2 // indirect
-	golang.org/x/crypto v0.40.0 // indirect
+	go.yaml.in/yaml/v3 v3.0.4 // indirect
+	golang.org/x/crypto v0.42.0 // indirect
 	golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
-	golang.org/x/mod v0.26.0 // indirect
-	golang.org/x/net v0.42.0 // indirect
+	golang.org/x/mod v0.28.0 // indirect
+	golang.org/x/net v0.44.0 // indirect
 	golang.org/x/oauth2 v0.30.0 // indirect
-	golang.org/x/sys v0.34.0 // indirect
-	golang.org/x/term v0.33.0 // indirect
-	golang.org/x/text v0.27.0 // indirect
+	golang.org/x/sys v0.36.0 // indirect
+	golang.org/x/term v0.35.0 // indirect
+	golang.org/x/text v0.29.0 // indirect
 	golang.org/x/time v0.12.0 // indirect
-	golang.org/x/tools v0.35.0 // indirect
-	golang.org/x/tools/go/expect v0.1.1-deprecated // indirect
+	golang.org/x/tools v0.37.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
-	gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 // indirect
+	gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/apiserver v0.33.3 // indirect
-	k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7 // indirect
+	k8s.io/apiserver v0.34.1 // indirect
+	k8s.io/gengo/v2 v2.0.0-20250820003526-c297c0c1eb9d // indirect
 	k8s.io/klog/v2 v2.130.1 // indirect
-	k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
+	k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3 // indirect
 	sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect
-	sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
+	sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
 	sigs.k8s.io/randfill v1.0.0 // indirect
 )
diff --git a/go.sum b/go.sum
index 9ea103f..81d1227 100644
--- a/go.sum
+++ b/go.sum
@@ -18,6 +18,8 @@ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJ
 github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
 github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
 github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
+github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
 github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
 github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
 github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0=
@@ -73,10 +75,10 @@ github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
 github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
 github.com/elastic/crd-ref-docs v0.2.0 h1:U17MyGX71j4qfKTvYxbR4qZGoA1hc2thy7kseGYmP+o=
 github.com/elastic/crd-ref-docs v0.2.0/go.mod h1:0bklkJhTG7nC6AVsdDi0wt5bGoqvzdZSzMMQkilZ6XM=
-github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk=
-github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
-github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
-github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
+github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
+github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
+github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
 github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
 github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
 github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
@@ -85,10 +87,10 @@ github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjT
 github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
 github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
-github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
-github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
-github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
+github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
+github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
+github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
+github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
 github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@@ -96,12 +98,12 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
 github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
-github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
-github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
+github.com/go-openapi/jsonpointer v0.21.2 h1:AqQaNADVwq/VnkCmQg6ogE+M3FOsKTytwges0JdwVuA=
+github.com/go-openapi/jsonpointer v0.21.2/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
 github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
 github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
-github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
-github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
+github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
+github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
 github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
 github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
 github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4=
@@ -118,11 +120,10 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
 github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
 github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
-github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4=
-github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo=
-github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
-github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=
+github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
+github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
+github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -168,8 +169,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
-github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
-github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
+github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
 github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
 github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
 github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
@@ -179,8 +180,9 @@ github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVO
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
+github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
@@ -194,10 +196,10 @@ github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s=
 github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
-github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
-github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
-github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
-github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
+github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw=
+github.com/onsi/ginkgo/v2 v2.25.3/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
+github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
+github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -209,16 +211,16 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
-github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
-github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
+github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
+github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
 github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
 github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
-github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
-github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
-github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
-github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
-github.com/prometheus/prometheus v0.305.0 h1:UO/LsM32/E9yBDtvQj8tN+WwhbyWKR10lO35vmFLx0U=
-github.com/prometheus/prometheus v0.305.0/go.mod h1:JG+jKIDUJ9Bn97anZiCjwCxRyAx+lpcEQ0QnZlUlbwY=
+github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
+github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
+github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
+github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
+github.com/prometheus/prometheus v0.306.0 h1:Q0Pvz/ZKS6vVWCa1VSgNyNJlEe8hxdRlKklFg7SRhNw=
+github.com/prometheus/prometheus v0.306.0/go.mod h1:7hMSGyZHt0dcmZ5r4kFPJ/vxPQU99N5/BGwSPDxeZrQ=
 github.com/prometheus/sigv4 v0.2.0 h1:qDFKnHYFswJxdzGeRP63c4HlH3Vbn1Yf/Ao2zabtVXk=
 github.com/prometheus/sigv4 v0.2.0/go.mod h1:D04rqmAaPPEUkjRQxGqjoxdyJuyCh6E0M18fZr0zBiE=
 github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
@@ -226,8 +228,9 @@ github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWN
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
 github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
-github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
+github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
 github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -239,8 +242,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
 github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -249,22 +252,22 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
 go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
-go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
-go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
+go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
+go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 h1:JgtbA0xkWHnTmYk7YusopJFX6uleBmAuZ8n05NEh8nQ=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0/go.mod h1:179AK5aar5R3eS9FucPy6rggvU0g52cvKId8pv4+v0c=
-go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
-go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
-go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
-go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
-go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
-go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
-go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
-go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
-go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI=
-go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc=
+go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
+go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
+go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
+go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
+go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
+go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
+go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
+go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
+go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
+go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
 go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
 go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
 go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
@@ -277,51 +280,51 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
 go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
 go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
 go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
-go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
-go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
+go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
+go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
-golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
+golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
+golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
 golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA=
 golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
-golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
+golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
+golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
-golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
+golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
+golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
 golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
 golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
-golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
+golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
-golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
-golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
+golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
+golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
+golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
-golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
+golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
+golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
 golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
 golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
-golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
+golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
+golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
 golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
 golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
 golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
@@ -332,21 +335,23 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
 gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-google.golang.org/api v0.238.0 h1:+EldkglWIg/pWjkq97sd+XxH7PxakNYoe/rkSTbnvOs=
-google.golang.org/api v0.238.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50=
-google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
-google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
-google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
-google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
-google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
-google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
+gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
+gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
+google.golang.org/api v0.239.0 h1:2hZKUnFZEy81eugPs4e2XzIJ5SOwQg0G82bpXD65Puo=
+google.golang.org/api v0.239.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50=
+google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b h1:ULiyYQ0FdsJhwwZUwbaXpZF5yUE3h+RA+gxvBu37ucc=
+google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b/go.mod h1:oDOGiMSXHL4sDTJvFvIB9nRQCGdLP1o/iVaqQK8zB+M=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 h1:pmJpJEvT846VzausCQ5d7KreSROcDqmO388w5YbnltA=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og=
+google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
+google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
+google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
+google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
-gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
+gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
+gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
@@ -356,43 +361,41 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8=
-k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE=
-k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs=
-k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8=
-k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA=
-k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
-k8s.io/apiserver v0.33.3 h1:Wv0hGc+QFdMJB4ZSiHrCgN3zL3QRatu56+rpccKC3J4=
-k8s.io/apiserver v0.33.3/go.mod h1:05632ifFEe6TxwjdAIrwINHWE2hLwyADFk5mBsQa15E=
-k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA=
-k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg=
-k8s.io/code-generator v0.33.3 h1:6+34LhYkIuQ/yn/E3qlpVqjQaP8smzCu4NE1A8b0LWs=
-k8s.io/code-generator v0.33.3/go.mod h1:6Y02+HQJYgNphv9z3wJB5w+sjYDIEBQW7sh62PkufvA=
-k8s.io/component-base v0.33.3 h1:mlAuyJqyPlKZM7FyaoM/LcunZaaY353RXiOd2+B5tGA=
-k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4=
-k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7 h1:2OX19X59HxDprNCVrWi6jb7LW1PoqTlYqEq5H2oetog=
-k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=
+k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=
+k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=
+k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI=
+k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc=
+k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
+k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
+k8s.io/apiserver v0.34.1 h1:U3JBGdgANK3dfFcyknWde1G6X1F4bg7PXuvlqt8lITA=
+k8s.io/apiserver v0.34.1/go.mod h1:eOOc9nrVqlBI1AFCvVzsob0OxtPZUCPiUJL45JOTBG0=
+k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY=
+k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8=
+k8s.io/code-generator v0.34.1 h1:WpphT26E+j7tEgIUfFr5WfbJrktCGzB3JoJH9149xYc=
+k8s.io/code-generator v0.34.1/go.mod h1:DeWjekbDnJWRwpw3s0Jat87c+e0TgkxoR4ar608yqvg=
+k8s.io/component-base v0.34.1 h1:v7xFgG+ONhytZNFpIz5/kecwD+sUhVE6HU7qQUiRM4A=
+k8s.io/component-base v0.34.1/go.mod h1:mknCpLlTSKHzAQJJnnHVKqjxR7gBeHRv0rPXA7gdtQ0=
+k8s.io/gengo/v2 v2.0.0-20250820003526-c297c0c1eb9d h1:qUrYOinhdAUL0xxhA4gPqogPBaS9nIq2l2kTb6pmeB0=
+k8s.io/gengo/v2 v2.0.0-20250820003526-c297c0c1eb9d/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
-k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
-k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
-k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3 h1:liMHz39T5dJO1aOKHLvwaCjDbf07wVh6yaUlTpunnkE=
+k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
+k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0=
+k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
-sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
-sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
-sigs.k8s.io/controller-tools v0.18.0 h1:rGxGZCZTV2wJreeRgqVoWab/mfcumTMmSwKzoM9xrsE=
-sigs.k8s.io/controller-tools v0.18.0/go.mod h1:gLKoiGBriyNh+x1rWtUQnakUYEujErjXs9pf+x/8n1U=
-sigs.k8s.io/gateway-api v1.3.0 h1:q6okN+/UKDATola4JY7zXzx40WO4VISk7i9DIfOvr9M=
-sigs.k8s.io/gateway-api v1.3.0/go.mod h1:d8NV8nJbaRbEKem+5IuxkL8gJGOZ+FJ+NvOIltV8gDk=
-sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
-sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
-sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/controller-runtime v0.22.1 h1:Ah1T7I+0A7ize291nJZdS1CabF/lB4E++WizgV24Eqg=
+sigs.k8s.io/controller-runtime v0.22.1/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY=
+sigs.k8s.io/controller-tools v0.19.0 h1:OU7jrPPiZusryu6YK0jYSjPqg8Vhf8cAzluP9XGI5uk=
+sigs.k8s.io/controller-tools v0.19.0/go.mod h1:y5HY/iNDFkmFla2CfQoVb2AQXMsBk4ad84iR1PLANB0=
+sigs.k8s.io/gateway-api v1.4.0 h1:ZwlNM6zOHq0h3WUX2gfByPs2yAEsy/EenYJB78jpQfQ=
+sigs.k8s.io/gateway-api v1.4.0/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk=
+sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
+sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
 sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
 sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
-sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
-sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
-sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
 sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
 sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
diff --git a/hack/release-quickstart.sh b/hack/release-quickstart.sh
index 22c7051..813146d 100755
--- a/hack/release-quickstart.sh
+++ b/hack/release-quickstart.sh
@@ -74,25 +74,21 @@ sed -i.bak "s|kubectl apply -k https://github.com/kubernetes-sigs/gateway-api-in
 # -----------------------------------------------------------------------------
 # Update image references
 # -----------------------------------------------------------------------------
-EPP="config/manifests/inferencepool-resources.yaml"
 #TODO: Put all helm values files into an array to loop over
 EPP_HELM="config/charts/inferencepool/values.yaml"
 BBR_HELM="config/charts/body-based-routing/values.yaml"
 CONFORMANCE_MANIFESTS="conformance/resources/base.yaml"
-echo "Updating ${EPP}, ${EPP_HELM}, ${BBR_HELM}, and ${CONFORMANCE_MANIFESTS} ..."
+echo "Updating ${EPP_HELM}, ${BBR_HELM}, and ${CONFORMANCE_MANIFESTS} ..."
 
 # Update the container tag.
-sed -i.bak -E "s|(us-central1-docker\.pkg\.dev/k8s-staging-images/gateway-api-inference-extension/epp:)[^\"[:space:]]+|\1${RELEASE_TAG}|g" "$EPP"
 sed -i.bak -E "s|(tag: )[^\"[:space:]]+|\1${RELEASE_TAG}|g" "$EPP_HELM"
 sed -i.bak -E "s|(tag: )[^\"[:space:]]+|\1${RELEASE_TAG}|g" "$BBR_HELM"
 sed -i.bak -E "s|(us-central1-docker\.pkg\.dev/k8s-staging-images/gateway-api-inference-extension/epp:)[^\"[:space:]]+|\1${RELEASE_TAG}|g" "$CONFORMANCE_MANIFESTS"
 
 # Update the container image pull policy.
-sed -i.bak '/us-central1-docker.pkg.dev\/k8s-staging-images\/gateway-api-inference-extension\/epp/{n;s/Always/IfNotPresent/;}' "$EPP"
 sed -i.bak '/us-central1-docker.pkg.dev\/k8s-staging-images\/gateway-api-inference-extension\/epp/{n;s/Always/IfNotPresent/;}' "$CONFORMANCE_MANIFESTS"
 
 # Update the container registry.
-sed -i.bak -E "s|us-central1-docker\.pkg\.dev/k8s-staging-images|registry.k8s.io|g" "$EPP"
 sed -i.bak -E "s|us-central1-docker\.pkg\.dev/k8s-staging-images|registry.k8s.io|g" "$EPP_HELM"
 sed -i.bak -E "s|us-central1-docker\.pkg\.dev/k8s-staging-images|registry.k8s.io|g" "$BBR_HELM"
 sed -i.bak -E "s|us-central1-docker\.pkg\.dev/k8s-staging-images|registry.k8s.io|g" "$CONFORMANCE_MANIFESTS"
@@ -136,11 +132,15 @@ sed -i.bak '/us-central1-docker.pkg.dev\/k8s-staging-images\/gateway-api-inferen
 # Update the container registry for lora-syncer in vLLM CPU and GPU deployment manifests.
 sed -i.bak -E "s|us-central1-docker\.pkg\.dev/k8s-staging-images|registry.k8s.io|g" "$VLLM_GPU_DEPLOY" "$VLLM_CPU_DEPLOY"
 
+# Update IGW_CHART_VERSION in quickstart guide to match the current release tag
+GUIDES_INDEX="site-src/guides/index.md"
+sed -i.bak -E "s/export IGW_CHART_VERSION=v[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?/export IGW_CHART_VERSION=${RELEASE_TAG}/g" "$GUIDES_INDEX"
+
 # -----------------------------------------------------------------------------
 # Stage the changes
 # -----------------------------------------------------------------------------
-echo "Staging $VERSION_FILE $UPDATED_CRD $README $EPP $EPP_HELM $BBR_HELM $CONFORMANCE_MANIFESTS $VLLM_GPU_DEPLOY $VLLM_CPU_DEPLOY $VLLM_SIM_DEPLOY files..."
-git add $VERSION_FILE $UPDATED_CRD $README $EPP $EPP_HELM $BBR_HELM $CONFORMANCE_MANIFESTS $VLLM_GPU_DEPLOY $VLLM_CPU_DEPLOY $VLLM_SIM_DEPLOY
+echo "Staging $VERSION_FILE $UPDATED_CRD $README $EPP_HELM $BBR_HELM $CONFORMANCE_MANIFESTS $VLLM_GPU_DEPLOY $VLLM_CPU_DEPLOY $VLLM_SIM_DEPLOY $GUIDES_INDEX files..."
+git add $VERSION_FILE $UPDATED_CRD $README $EPP_HELM $BBR_HELM $CONFORMANCE_MANIFESTS $VLLM_GPU_DEPLOY $VLLM_CPU_DEPLOY $VLLM_SIM_DEPLOY $GUIDES_INDEX
 
 # -----------------------------------------------------------------------------
 # Cleanup backup files and finish
diff --git a/hack/verify-helm.sh b/hack/verify-helm.sh
new file mode 100755
index 0000000..0388b6e
--- /dev/null
+++ b/hack/verify-helm.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# Copyright 2025 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/..
+
+declare -A test_cases_inference_pool
+
+# InferencePool Helm Chart test cases
+test_cases_inference_pool["basic"]="--set inferencePool.modelServers.matchLabels.app=llm-instance-gateway"
+test_cases_inference_pool["gke-provider"]="--set provider.name=gke --set inferencePool.modelServers.matchLabels.app=llm-instance-gateway"
+test_cases_inference_pool["multiple-replicas"]="--set inferencePool.replicas=3 --set inferencePool.modelServers.matchLabels.app=llm-instance-gateway"
+
+# Run the install command in case this script runs from a different bash
+# source (such as in the verify-all script)
+make helm-install
+
+# Running tests cases
+echo "Running helm template command for inferencePool chart..."
+# Loop through the keys of the associative array
+for key in "${!test_cases_inference_pool[@]}"; do
+  echo "Running test: $key"
+  ${SCRIPT_ROOT}/bin/helm template ${SCRIPT_ROOT}/config/charts/inferencepool ${test_cases_inference_pool[$key]} --output-dir="${SCRIPT_ROOT}/bin"
+  if [ $? -ne 0 ]; then
+    echo "Helm template command failed for test: $key"
+    exit 1
+  fi
+done
+
+
+
diff --git a/hack/verify-manifests.sh b/hack/verify-manifests.sh
index 70d819b..d74c277 100755
--- a/hack/verify-manifests.sh
+++ b/hack/verify-manifests.sh
@@ -38,12 +38,15 @@ main() {
   cp ${SCRIPT_ROOT}/config/crd/bases/* "${TEMP_DIR}/"
 
   # Download external CRDs for validation
+  fetch_crds "https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/refs/tags/${GATEWAY_API_VERSION}/config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml"
   fetch_crds "https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/refs/tags/${GATEWAY_API_VERSION}/config/crd/standard/gateway.networking.k8s.io_gateways.yaml"
   fetch_crds "https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/refs/tags/${GATEWAY_API_VERSION}/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml"
   fetch_crds "https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/tags/${GKE_GATEWAY_API_VERSION}/config/crd/networking.gke.io_gcpbackendpolicies.yaml"
   fetch_crds "https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/tags/${GKE_GATEWAY_API_VERSION}/config/crd/networking.gke.io_healthcheckpolicies.yaml"
   fetch_crds "https://raw.githubusercontent.com/istio/istio/refs/tags/${ISTIO_VERSION}/manifests/charts/base/files/crd-all.gen.yaml"
 
+  # Run the install command in case this script runs from a different bash
+  # source (such as in the verify-all script)
   make kubectl-validate
 
   ${SCRIPT_ROOT}/bin/kubectl-validate "${TEMP_DIR}"
diff --git a/internal/runnable/grpc.go b/internal/runnable/grpc.go
index 82b7b85..5db5f9e 100644
--- a/internal/runnable/grpc.go
+++ b/internal/runnable/grpc.go
@@ -37,8 +37,7 @@ func GRPCServer(name string, srv *grpc.Server, port int) manager.Runnable {
 		// Start listening.
 		lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
 		if err != nil {
-			log.Error(err, "gRPC server failed to listen")
-			return err
+			return fmt.Errorf("gRPC server failed to listen - %w", err)
 		}
 
 		log.Info("gRPC server listening", "port", port)
@@ -59,8 +58,7 @@ func GRPCServer(name string, srv *grpc.Server, port int) manager.Runnable {
 
 		// Keep serving until terminated.
 		if err := srv.Serve(lis); err != nil && err != grpc.ErrServerStopped {
-			log.Error(err, "gRPC server failed")
-			return err
+			return fmt.Errorf("gRPC server failed - %w", err)
 		}
 		log.Info("gRPC server terminated")
 		return nil
diff --git a/mkdocs.yml b/mkdocs.yml
index 4bb94f5..4c285c2 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -12,6 +12,8 @@ theme:
   logo: images/logo/logo-text-large-horizontal-white.png
   favicon: images/favicon-64.png
   features:
+    - content.code.annotate
+    - content.code.copy
     - search.highlight
     - navigation.tabs
     - navigation.top
@@ -55,7 +57,8 @@ nav:
         Design Principles: concepts/design-principles.md
         Conformance: concepts/conformance.md
         Roles and Personas: concepts/roles-and-personas.md
-    - Implementations: 
+        Priority and Capacity: concepts/priority-and-capacity.md
+    - Implementations:
       - Gateways: implementations/gateways.md
       - Model Servers: implementations/model-servers.md
     - FAQ: faq.md
@@ -64,14 +67,14 @@ nav:
       - Getting started: guides/index.md
       - Use Cases:
         - Serve Multiple GenAI models: guides/serve-multiple-genai-models.md
-        - Serve Multiple LoRA adapters: guides/serve-multiple-lora-adapters.md
       - Rollout:
         - Adapter Rollout: guides/adapter-rollout.md
         - InferencePool Rollout: guides/inferencepool-rollout.md
       - Metrics and Observability: guides/metrics-and-observability.md
       - Configuration Guide:
-          - Configuring the plugins via configuration files or text: guides/epp-configuration/config-text.md    
+          - Configuring the plugins via configuration YAML file: guides/epp-configuration/config-text.md
           - Prefix Cache Aware Plugin: guides/epp-configuration/prefix-aware.md
+      - Troubleshooting Guide: guides/troubleshooting.md
     - Implementer Guides:
       - Getting started: guides/implementers.md
       - Conformance Tests: guides/conformance-tests.md
@@ -79,11 +82,16 @@ nav:
     - Benchmark: performance/benchmark/index.md
     - Regression Testing: performance/regression-testing/index.md
   - Reference:
-    - API Reference: reference/spec.md
+    - v1 API Reference: reference/spec.md
+    - v1alpha1 API Reference:
+      - reference/x-v1a1-spec.md
+    - v1alpha2 API Reference:
+      - reference/x-v1a2-spec.md
     - API Types:
       - InferencePool: api-types/inferencepool.md
-      - InferenceModel: api-types/inferencemodel.md
+      - InferenceObjective: api-types/inferenceobjective.md
+      - InferencePoolImport: api-types/inferencepoolimport.md
   - Enhancements:
-    - Overview: gieps/overview.md
+    - Overview: enhancements/overview.md
   - Contributing:
     - How to Get Involved: contributing/index.md
diff --git a/pkg/bbr/README.md b/pkg/bbr/README.md
index b5b6f77..80ab383 100644
--- a/pkg/bbr/README.md
+++ b/pkg/bbr/README.md
@@ -8,7 +8,3 @@ body of the HTTP request. However, most implementations do not support routing
 based on the request body. This extension helps bridge that gap for clients.
 This extension works by parsing the request body. If it finds a `model` parameter in the
 request body, it will copy the value of that parameter into a request header.
-
-This extension is intended to be paired with an `ext_proc` capable Gateway. There is not
-a standard way to represent this kind of extension in Gateway API yet, so we recommend
-referring to implementation-specific documentation for how to deploy this extension.
diff --git a/pkg/bbr/handlers/server.go b/pkg/bbr/handlers/server.go
index 499d6af..6488453 100644
--- a/pkg/bbr/handlers/server.go
+++ b/pkg/bbr/handlers/server.go
@@ -61,9 +61,6 @@ func (s *Server) Process(srv extProcPb.ExternalProcessor_ProcessServer) error {
 			return nil
 		}
 		if recvErr != nil {
-			// This error occurs very frequently, though it doesn't seem to have any impact.
-			// TODO Figure out if we can remove this noise.
-			loggerVerbose.Error(recvErr, "Cannot receive stream request")
 			return status.Errorf(codes.Unknown, "cannot receive stream request: %v", recvErr)
 		}
 
diff --git a/pkg/bbr/server/runserver.go b/pkg/bbr/server/runserver.go
index ec2880b..ac6ac41 100644
--- a/pkg/bbr/server/runserver.go
+++ b/pkg/bbr/server/runserver.go
@@ -19,6 +19,7 @@ package server
 import (
 	"context"
 	"crypto/tls"
+	"fmt"
 
 	extProcPb "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
 	"github.com/go-logr/logr"
@@ -54,8 +55,7 @@ func (r *ExtProcServerRunner) AsRunnable(logger logr.Logger) manager.Runnable {
 		if r.SecureServing {
 			cert, err := tlsutil.CreateSelfSignedTLSCertificate(logger)
 			if err != nil {
-				logger.Error(err, "Failed to create self signed certificate")
-				return err
+				return fmt.Errorf("failed to create self signed certificate - %w", err)
 			}
 			creds := credentials.NewTLS(&tls.Config{Certificates: []tls.Certificate{cert}})
 			srv = grpc.NewServer(grpc.Creds(creds))
diff --git a/pkg/epp/README.md b/pkg/epp/README.md
index df5c213..966aed5 100644
--- a/pkg/epp/README.md
+++ b/pkg/epp/README.md
@@ -20,9 +20,4 @@ An EPP instance handles a single `InferencePool` (and so for each `InferencePool
   - The EPP generates metrics to enhance observability.
   - It reports InferenceObjective-level metrics, further broken down by target model.
   - Detailed information regarding metrics can be found on the [website](https://gateway-api-inference-extension.sigs.k8s.io/guides/metrics/).
-
-
-## Scheduling Algorithm 
-The scheduling package implements request scheduling algorithms for load balancing requests across backend pods in an inference gateway. The scheduler ensures efficient resource utilization while maintaining low latency and prioritizing critical requests. It applies a series of filters based on metrics and heuristics to select the best pod for a given request. The following flow chart summarizes the current scheduling algorithm
-
-<img src="../../docs/scheduler-flowchart.png" alt="Scheduling Algorithm" width="400" />
+  
\ No newline at end of file
diff --git a/pkg/epp/backend/metrics/metrics.go b/pkg/epp/backend/metrics/metrics.go
index 9f53661..e10098f 100644
--- a/pkg/epp/backend/metrics/metrics.go
+++ b/pkg/epp/backend/metrics/metrics.go
@@ -25,6 +25,7 @@ import (
 
 	dto "github.com/prometheus/client_model/go"
 	"github.com/prometheus/common/expfmt"
+	"github.com/prometheus/common/model"
 	"go.uber.org/multierr"
 
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend"
@@ -65,7 +66,7 @@ func (p *PodMetricsClientImpl) FetchMetrics(ctx context.Context, pod *backend.Po
 		return nil, fmt.Errorf("unexpected status code from %s: %v", pod.NamespacedName, resp.StatusCode)
 	}
 
-	parser := expfmt.TextParser{}
+	parser := expfmt.NewTextParser(model.LegacyValidation)
 	metricFamilies, err := parser.TextToMetricFamilies(resp.Body)
 	if err != nil {
 		return nil, err
diff --git a/pkg/epp/config/loader/defaults.go b/pkg/epp/config/loader/defaults.go
index 7be0d98..2a8236e 100644
--- a/pkg/epp/config/loader/defaults.go
+++ b/pkg/epp/config/loader/defaults.go
@@ -69,7 +69,7 @@ func setDefaultsPhaseTwo(cfg *configapi.EndpointPickerConfig, handle plugins.Han
 		thePlugins := []configapi.SchedulingPlugin{}
 		for pluginName, plugin := range allPlugins {
 			switch plugin.(type) {
-			case framework.Filter, framework.Picker, framework.PostCycle, framework.Scorer:
+			case framework.Filter, framework.Scorer, framework.Picker:
 				thePlugins = append(thePlugins, configapi.SchedulingPlugin{PluginRef: pluginName})
 			}
 		}
diff --git a/pkg/epp/controller/inferenceobjective_reconciler.go b/pkg/epp/controller/inferenceobjective_reconciler.go
index 53bce86..c8ac5a6 100644
--- a/pkg/epp/controller/inferenceobjective_reconciler.go
+++ b/pkg/epp/controller/inferenceobjective_reconciler.go
@@ -18,6 +18,7 @@ package controller
 
 import (
 	"context"
+	"fmt"
 
 	"k8s.io/apimachinery/pkg/api/errors"
 	ctrl "sigs.k8s.io/controller-runtime"
@@ -48,8 +49,7 @@ func (c *InferenceObjectiveReconciler) Reconcile(ctx context.Context, req ctrl.R
 	notFound := false
 	if err := c.Get(ctx, req.NamespacedName, infObjective); err != nil {
 		if !errors.IsNotFound(err) {
-			logger.Error(err, "Unable to get InferenceObjective")
-			return ctrl.Result{}, err
+			return ctrl.Result{}, fmt.Errorf("unable to get InferenceObjective - %w", err)
 		}
 		notFound = true
 	}
diff --git a/pkg/epp/controller/inferencepool_reconciler.go b/pkg/epp/controller/inferencepool_reconciler.go
index d8b7668..3b52de0 100644
--- a/pkg/epp/controller/inferencepool_reconciler.go
+++ b/pkg/epp/controller/inferencepool_reconciler.go
@@ -56,9 +56,7 @@ func (c *InferencePoolReconciler) Reconcile(ctx context.Context, req ctrl.Reques
 		obj = &v1alpha2.InferencePool{}
 	default:
 		// Handle unsupported groups gracefully.
-		err := fmt.Errorf("unsupported API group: %s", c.PoolGKNN.Group)
-		logger.Error(err, "Cannot reconcile InferencePool")
-		return ctrl.Result{}, err
+		return ctrl.Result{}, fmt.Errorf("cannot reconcile InferencePool - unsupported API group: %s", c.PoolGKNN.Group)
 	}
 
 	// 2. Perform a single, generic fetch for the object.
@@ -68,8 +66,7 @@ func (c *InferencePoolReconciler) Reconcile(ctx context.Context, req ctrl.Reques
 			c.Datastore.Clear()
 			return ctrl.Result{}, nil
 		}
-		logger.Error(err, "Unable to get InferencePool")
-		return ctrl.Result{}, err
+		return ctrl.Result{}, fmt.Errorf("unable to get InferencePool - %w", err)
 	}
 
 	// 3. Perform common checks using the client.Object interface.
@@ -90,16 +87,14 @@ func (c *InferencePoolReconciler) Reconcile(ctx context.Context, req ctrl.Reques
 		var err error
 		err = pool.ConvertTo(v1infPool)
 		if err != nil {
-			logger.Error(err, "Failed to convert XInferencePool to InferencePool")
-			return ctrl.Result{}, err
+			return ctrl.Result{}, fmt.Errorf("failed to convert XInferencePool to InferencePool - %w", err)
 		}
 	default:
 		return ctrl.Result{}, fmt.Errorf("unsupported API group: %s", c.PoolGKNN.Group)
 	}
 
 	if err := c.Datastore.PoolSet(ctx, c.Reader, v1infPool); err != nil {
-		logger.Error(err, "Failed to update datastore")
-		return ctrl.Result{}, err
+		return ctrl.Result{}, fmt.Errorf("failed to update datastore - %w", err)
 	}
 
 	return ctrl.Result{}, nil
diff --git a/pkg/epp/controller/pod_reconciler.go b/pkg/epp/controller/pod_reconciler.go
index 3cd7c25..ce77b2c 100644
--- a/pkg/epp/controller/pod_reconciler.go
+++ b/pkg/epp/controller/pod_reconciler.go
@@ -18,6 +18,7 @@ package controller
 
 import (
 	"context"
+	"fmt"
 
 	"github.com/go-logr/logr"
 	corev1 "k8s.io/api/core/v1"
@@ -55,8 +56,7 @@ func (c *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
 			c.Datastore.PodDelete(req.NamespacedName)
 			return ctrl.Result{}, nil
 		}
-		logger.V(logutil.DEFAULT).Error(err, "Unable to get pod")
-		return ctrl.Result{}, err
+		return ctrl.Result{}, fmt.Errorf("unable to get pod - %w", err)
 	}
 
 	c.updateDatastore(logger, pod)
diff --git a/pkg/epp/datalayer/collector.go b/pkg/epp/datalayer/collector.go
index 87d2a62..86a8f7b 100644
--- a/pkg/epp/datalayer/collector.go
+++ b/pkg/epp/datalayer/collector.go
@@ -82,17 +82,18 @@ func NewCollector() *Collector {
 }
 
 // Start initiates data source collection for the endpoint.
+// TODO: pass PoolInfo for backward compatibility
 func (c *Collector) Start(ctx context.Context, ticker Ticker, ep Endpoint, sources []DataSource) error {
 	var ready chan struct{}
 	started := false
 
 	c.startOnce.Do(func() {
+		logger := log.FromContext(ctx).WithValues("endpoint", ep.GetPod().GetIPAddress())
 		c.ctx, c.cancel = context.WithCancel(ctx)
 		started = true
 		ready = make(chan struct{})
 
 		go func(endpoint Endpoint, sources []DataSource) {
-			logger := log.FromContext(ctx).WithValues("endpoint", ep.GetPod().GetIPAddress())
 			logger.V(logging.DEFAULT).Info("starting collection")
 
 			defer func() {
@@ -107,6 +108,7 @@ func (c *Collector) Start(ctx context.Context, ticker Ticker, ep Endpoint, sourc
 				case <-c.ctx.Done(): // per endpoint context cancelled
 					return
 				case <-ticker.Channel():
+					// TODO: do not collect if there's no pool specified?
 					for _, src := range sources {
 						ctx, cancel := context.WithTimeout(c.ctx, defaultCollectionTimeout)
 						_ = src.Collect(ctx, endpoint) // TODO: track errors per collector?
diff --git a/pkg/epp/datalayer/datasource.go b/pkg/epp/datalayer/datasource.go
index 6ad7b29..737e2c5 100644
--- a/pkg/epp/datalayer/datasource.go
+++ b/pkg/epp/datalayer/datasource.go
@@ -92,14 +92,27 @@ func (dsr *DataSourceRegistry) GetSources() []DataSource {
 
 // --- default registry accessors ---
 
+// RegisterSource adds a new data source to the default registry.
 func RegisterSource(src DataSource) error {
 	return defaultDataSources.Register(src)
 }
 
-func GetNamedSource(name string) (DataSource, bool) {
-	return defaultDataSources.GetNamedSource(name)
+// GetNamedSource returns a typed data source from the default registry.
+func GetNamedSource[T DataSource](name string) (T, bool) {
+	v, ok := defaultDataSources.GetNamedSource(name)
+	if !ok {
+		var zero T
+		return zero, false
+	}
+	src, ok := v.(T)
+	if !ok {
+		var zero T
+		return zero, false
+	}
+	return src, true
 }
 
+// GetSources returns the list of data sources registered in the default registry.
 func GetSources() []DataSource {
 	return defaultDataSources.GetSources()
 }
diff --git a/pkg/epp/datalayer/factory.go b/pkg/epp/datalayer/factory.go
index a282069..eca7697 100644
--- a/pkg/epp/datalayer/factory.go
+++ b/pkg/epp/datalayer/factory.go
@@ -18,8 +18,12 @@ package datalayer
 
 import (
 	"context"
+	"sync"
+	"time"
 
 	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/log"
 
 	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
 )
@@ -44,3 +48,74 @@ type EndpointFactory interface {
 	NewEndpoint(parent context.Context, inpod *corev1.Pod, poolinfo PoolInfo) Endpoint
 	ReleaseEndpoint(ep Endpoint)
 }
+
+// EndpointLifecycle manages the life cycle (creation and termination) of
+// endpoints.
+type EndpointLifecycle struct {
+	sources         []DataSource  // data sources for collectors
+	collectors      sync.Map      // collectors map. key: Pod namespaced name, value: *Collector
+	refreshInterval time.Duration // metrics refresh interval
+}
+
+// NewEndpointFactory returns a new endpoint for factory, managing collectors for
+// its endpoints. This function assumes that sources are not modified afterwards.
+func NewEndpointFactory(sources []DataSource, refreshMetricsInterval time.Duration) *EndpointLifecycle {
+	return &EndpointLifecycle{
+		sources:         sources,
+		collectors:      sync.Map{},
+		refreshInterval: refreshMetricsInterval,
+	}
+}
+
+// NewEndpoint implements EndpointFactory.NewEndpoint.
+// Creates a new endpoint and starts its associated collector with its own ticker.
+// Guards against multiple concurrent calls for the same endpoint.
+func (lc *EndpointLifecycle) NewEndpoint(parent context.Context, inpod *corev1.Pod, _ PoolInfo) Endpoint {
+	key := types.NamespacedName{Namespace: inpod.Namespace, Name: inpod.Name}
+	logger := log.FromContext(parent).WithValues("pod", key)
+
+	if _, ok := lc.collectors.Load(key); ok {
+		logger.Info("collector already running for endpoint", "endpoint", key)
+		return nil
+	}
+
+	endpoint := NewEndpoint()
+	endpoint.UpdatePod(inpod)
+	collector := NewCollector() // for full backward compatibility, set the logger and poolinfo
+
+	if _, loaded := lc.collectors.LoadOrStore(key, collector); loaded {
+		// another goroutine already created and stored a collector for this endpoint.
+		// No need to start the new collector.
+		logger.Info("collector already running for endpoint", "endpoint", key)
+		return nil
+	}
+
+	ticker := NewTimeTicker(lc.refreshInterval)
+	if err := collector.Start(parent, ticker, endpoint, lc.sources); err != nil {
+		logger.Error(err, "failed to start collector for endpoint", "endpoint", key)
+		lc.collectors.Delete(key)
+	}
+
+	return endpoint
+}
+
+// ReleaseEndpoint implements EndpointFactory.ReleaseEndpoint
+// Stops the collector and cleans up resources for the endpoint
+func (lc *EndpointLifecycle) ReleaseEndpoint(ep Endpoint) {
+	key := ep.GetPod().GetNamespacedName()
+
+	if value, ok := lc.collectors.LoadAndDelete(key); ok {
+		collector := value.(*Collector)
+		_ = collector.Stop()
+	}
+}
+
+// Shutdown gracefully stops all collectors and cleans up all resources.
+func (lc *EndpointLifecycle) Shutdown() {
+	lc.collectors.Range(func(key, value any) bool {
+		collector := value.(*Collector)
+		_ = collector.Stop()
+		lc.collectors.Delete(key)
+		return true
+	})
+}
diff --git a/pkg/epp/datalayer/metrics/client.go b/pkg/epp/datalayer/metrics/client.go
index 7961b92..962a2a5 100644
--- a/pkg/epp/datalayer/metrics/client.go
+++ b/pkg/epp/datalayer/metrics/client.go
@@ -33,22 +33,31 @@ type Client interface {
 	Get(ctx context.Context, target *url.URL, ep datalayer.Addressable) (PrometheusMetricMap, error)
 }
 
-// -- package implementations --
 const (
+	// the maximum idle connection count is shared by all endpoints. The value is
+	// set high to ensure the number of idle connection is above the expected
+	// endpoint count. Setting it too low would cause thrashing of the idle connection
+	// pool and incur higher overheads for every GET (e.g., socket initiation, certificate
+	// exchange, connections in timed wait state, etc.).
 	maxIdleConnections = 5000
-	maxIdleTime        = 10 * time.Second
-	timeout            = 10 * time.Second
+	maxIdleTime        = 10 * time.Second // once a endpoint goes down, allow closing.
+	timeout            = 10 * time.Second // mostly guard against unresponsive endpoints.
+	// allow some grace when connections are not made idle immediately (e.g., parsing
+	// and updating might take some time). This allows maintaining up to two idle connections
+	// per endpoint (defined as scheme://host:port).
+	maxIdleConnsPerHost = 2
 )
 
 var (
+	baseTransport = &http.Transport{
+		MaxIdleConns:        maxIdleConnections,
+		MaxIdleConnsPerHost: maxIdleConnsPerHost,
+		// TODO: set additional timeouts, transport options, etc.
+	}
 	defaultClient = &client{
 		Client: http.Client{
-			Timeout: timeout,
-			Transport: &http.Transport{
-				MaxIdleConns:        maxIdleConnections,
-				MaxIdleConnsPerHost: 4, // host is defined as scheme://host:port
-			},
-			// TODO: set additional timeouts, transport options, etc.
+			Timeout:   timeout,
+			Transport: baseTransport,
 		},
 	}
 )
diff --git a/pkg/epp/datalayer/metrics/datasource.go b/pkg/epp/datalayer/metrics/datasource.go
index 5ff7ef9..7dcdc97 100644
--- a/pkg/epp/datalayer/metrics/datasource.go
+++ b/pkg/epp/datalayer/metrics/datasource.go
@@ -18,6 +18,7 @@ package metrics
 
 import (
 	"context"
+	"crypto/tls"
 	"errors"
 	"fmt"
 	"net"
@@ -30,7 +31,7 @@ import (
 )
 
 const (
-	dataSourceName = "metrics-data-source"
+	DataSourceName = "metrics-data-source"
 )
 
 // DataSource is a Model Server Protocol (MSP) compliant metrics data source,
@@ -44,9 +45,19 @@ type DataSource struct {
 	extractors sync.Map // key: name, value: extractor
 }
 
-// NewDataSource returns a new MSP compliant metrics data source, configured with the provided
-// client factory. If ClientFactory is nil, a default factory is used.
-func NewDataSource(metricsScheme string, metricsPort int32, metricsPath string, cl Client) *DataSource {
+// NewDataSource returns a new MSP compliant metrics data source, configured with
+// the provided client factory. If ClientFactory is nil, a default factory is used.
+// The Scheme, port and path are command line options. It should be noted that
+// a port value of zero is set if the command line is unspecified.
+func NewDataSource(metricsScheme string, metricsPort int32, metricsPath string, skipCertVerification bool, cl Client) *DataSource {
+	if metricsScheme == "https" {
+		httpsTransport := baseTransport.Clone()
+		httpsTransport.TLSClientConfig = &tls.Config{
+			InsecureSkipVerify: skipCertVerification,
+		}
+		defaultClient.Transport = httpsTransport
+	}
+
 	if cl == nil {
 		cl = defaultClient
 	}
@@ -61,14 +72,23 @@ func NewDataSource(metricsScheme string, metricsPort int32, metricsPath string,
 }
 
 // SetPort updates the port used for metrics scraping.
+// The port value can only be set once (i.e., if set by command line,
+// do not overwrite from Pool.Spec). A port value of 0 (i.e., unspecified
+// command line value) is ignored.
+// TODO: https://github.com/kubernetes-sigs/gateway-api-inference-extension/issues/1398
 func (dataSrc *DataSource) SetPort(metricsPort int32) {
-	port := strconv.Itoa(int(metricsPort))
-	dataSrc.metricsPort.Store(&port)
+	if dataSrc.metricsPort.Load() != nil { // do not overwrite
+		return
+	}
+	if metricsPort != 0 { // ignore zero value for port
+		port := strconv.Itoa(int(metricsPort))
+		dataSrc.metricsPort.Store(&port)
+	}
 }
 
 // Name returns the metrics data source name.
 func (dataSrc *DataSource) Name() string {
-	return dataSourceName
+	return DataSourceName
 }
 
 // AddExtractor adds an extractor to the data source, validating it can process
diff --git a/pkg/epp/datalayer/metrics/logger.go b/pkg/epp/datalayer/metrics/logger.go
new file mode 100644
index 0000000..fac757d
--- /dev/null
+++ b/pkg/epp/datalayer/metrics/logger.go
@@ -0,0 +1,138 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package metrics
+
+import (
+	"context"
+	"time"
+
+	"github.com/go-logr/logr"
+	"sigs.k8s.io/controller-runtime/pkg/log"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datalayer"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metrics"
+	logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
+)
+
+const debugPrintInterval = 5 * time.Second
+
+// StartMetricsLogger starts background goroutines for:
+// 1. Refreshing Prometheus metrics periodically
+// 2. Debug logging (if DEBUG level enabled)
+func StartMetricsLogger(ctx context.Context, datastore datalayer.PoolInfo, refreshInterval, stalenessThreshold time.Duration) {
+	logger := log.FromContext(ctx)
+
+	go runPrometheusRefresher(ctx, logger, datastore, refreshInterval, stalenessThreshold)
+
+	if logger.V(logutil.DEBUG).Enabled() {
+		go runDebugLogger(ctx, logger, datastore, stalenessThreshold)
+	}
+}
+
+func runPrometheusRefresher(ctx context.Context, logger logr.Logger, datastore datalayer.PoolInfo, interval, stalenessThreshold time.Duration) {
+	ticker := time.NewTicker(interval)
+	defer ticker.Stop()
+
+	for {
+		select {
+		case <-ctx.Done():
+			logger.V(logutil.DEFAULT).Info("Shutting down prometheus metrics thread")
+			return
+		case <-ticker.C:
+			refreshPrometheusMetrics(logger, datastore, stalenessThreshold)
+		}
+	}
+}
+
+func runDebugLogger(ctx context.Context, logger logr.Logger, datastore datalayer.PoolInfo, stalenessThreshold time.Duration) {
+	ticker := time.NewTicker(debugPrintInterval)
+	defer ticker.Stop()
+
+	for {
+		select {
+		case <-ctx.Done():
+			logger.V(logutil.DEFAULT).Info("Shutting down metrics logger thread")
+			return
+		case <-ticker.C:
+			printDebugMetrics(logger, datastore, stalenessThreshold)
+		}
+	}
+}
+
+func podsWithFreshMetrics(stalenessThreshold time.Duration) func(datalayer.Endpoint) bool {
+	return func(ep datalayer.Endpoint) bool {
+		if ep == nil {
+			return false // Skip nil pods
+		}
+		return time.Since(ep.GetMetrics().UpdateTime) <= stalenessThreshold
+	}
+}
+
+func podsWithStaleMetrics(stalenessThreshold time.Duration) func(datalayer.Endpoint) bool {
+	return func(ep datalayer.Endpoint) bool {
+		if ep == nil {
+			return false // Skip nil pods
+		}
+		return time.Since(ep.GetMetrics().UpdateTime) > stalenessThreshold
+	}
+}
+
+func printDebugMetrics(logger logr.Logger, datastore datalayer.PoolInfo, stalenessThreshold time.Duration) {
+	freshPods := datastore.PodList(podsWithFreshMetrics(stalenessThreshold))
+	stalePods := datastore.PodList(podsWithStaleMetrics(stalenessThreshold))
+
+	logger.V(logutil.VERBOSE).Info("Current Pods and metrics gathered",
+		"Fresh metrics", freshPods, "Stale metrics", stalePods)
+}
+
+func refreshPrometheusMetrics(logger logr.Logger, datastore datalayer.PoolInfo, stalenessThreshold time.Duration) {
+	pool, err := datastore.PoolGet()
+	if err != nil {
+		logger.V(logutil.DEFAULT).Info("Pool is not initialized, skipping refreshing metrics")
+		return
+	}
+
+	podMetrics := datastore.PodList(podsWithFreshMetrics(stalenessThreshold))
+	logger.V(logutil.TRACE).Info("Refreshing Prometheus Metrics", "ReadyPods", len(podMetrics))
+
+	if len(podMetrics) == 0 {
+		return
+	}
+
+	totals := calculateTotals(podMetrics)
+	podCount := len(podMetrics)
+
+	metrics.RecordInferencePoolAvgKVCache(pool.Name, totals.kvCache/float64(podCount))
+	metrics.RecordInferencePoolAvgQueueSize(pool.Name, float64(totals.queueSize/podCount))
+	metrics.RecordInferencePoolReadyPods(pool.Name, float64(podCount))
+}
+
+// totals holds aggregated metric values
+type totals struct {
+	kvCache   float64
+	queueSize int
+}
+
+func calculateTotals(endpoints []datalayer.Endpoint) totals {
+	var result totals
+	for _, pod := range endpoints {
+		metrics := pod.GetMetrics()
+		result.kvCache += metrics.KVCacheUsagePercent
+		result.queueSize += metrics.WaitingQueueSize
+	}
+	return result
+}
diff --git a/pkg/epp/datastore/datastore.go b/pkg/epp/datastore/datastore.go
index 00275b9..86204be 100644
--- a/pkg/epp/datastore/datastore.go
+++ b/pkg/epp/datastore/datastore.go
@@ -33,6 +33,7 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
 	backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datalayer"
+	dlmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datalayer/metrics"
 	logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
 	podutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/pod"
 )
@@ -116,6 +117,11 @@ func (ds *datastore) PoolSet(ctx context.Context, reader client.Reader, pool *v1
 
 	oldPool := ds.pool
 	ds.pool = pool
+	if oldPool == nil || pool.Spec.TargetPorts[0] != oldPool.Spec.TargetPorts[0] {
+		if source, found := datalayer.GetNamedSource[*dlmetrics.DataSource](dlmetrics.DataSourceName); found {
+			source.SetPort(int32(pool.Spec.TargetPorts[0].Number))
+		}
+	}
 	if oldPool == nil || !reflect.DeepEqual(pool.Spec.Selector, oldPool.Spec.Selector) {
 		logger.V(logutil.DEFAULT).Info("Updating inference pool endpoints", "selector", pool.Spec.Selector)
 		// A full resync is required to address two cases:
@@ -250,7 +256,7 @@ func (ds *datastore) podResyncAll(ctx context.Context, reader client.Reader) err
 		}
 		namespacedName := types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}
 		activePods[pod.Name] = true
-		if ds.PodUpdateOrAddIfNotExist(&pod) {
+		if !ds.PodUpdateOrAddIfNotExist(&pod) {
 			logger.V(logutil.DEFAULT).Info("Pod added", "name", namespacedName)
 		} else {
 			logger.V(logutil.DEFAULT).Info("Pod already exists", "name", namespacedName)
diff --git a/pkg/epp/flowcontrol/config.go b/pkg/epp/flowcontrol/config.go
new file mode 100644
index 0000000..edc23ab
--- /dev/null
+++ b/pkg/epp/flowcontrol/config.go
@@ -0,0 +1,50 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package flowcontrol
+
+import (
+	"fmt"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/controller"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/registry"
+)
+
+// Config is the top-level configuration for the entire flow control module.
+// It embeds the configurations for the controller and the registry, providing a single point of entry for validation
+// and initialization.
+type Config struct {
+	Controller controller.Config
+	Registry   registry.Config
+}
+
+// ValidateAndApplyDefaults checks the configuration for validity and populates any empty fields with system defaults.
+// It delegates validation to the underlying controller and registry configurations.
+// It returns a new, validated `Config` object and does not mutate the receiver.
+func (c *Config) ValidateAndApplyDefaults() (*Config, error) {
+	validatedControllerCfg, err := c.Controller.ValidateAndApplyDefaults()
+	if err != nil {
+		return nil, fmt.Errorf("controller config validation failed: %w", err)
+	}
+	validatedRegistryCfg, err := c.Registry.ValidateAndApplyDefaults()
+	if err != nil {
+		return nil, fmt.Errorf("registry config validation failed: %w", err)
+	}
+	return &Config{
+		Controller: *validatedControllerCfg,
+		Registry:   *validatedRegistryCfg,
+	}, nil
+}
diff --git a/pkg/epp/flowcontrol/contracts/doc.go b/pkg/epp/flowcontrol/contracts/doc.go
new file mode 100644
index 0000000..554f54e
--- /dev/null
+++ b/pkg/epp/flowcontrol/contracts/doc.go
@@ -0,0 +1,29 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package contracts defines the boundaries and service interfaces for the Flow Control system.
+//
+// Adhering to a "Ports and Adapters" (Hexagonal) architectural style, these interfaces decouple the core
+// `controller.FlowController` engine from its dependencies. They establish the required behaviors and system invariants
+// that concrete implementations must uphold.
+//
+// The primary contracts are:
+//
+//   - `FlowRegistry`: The interface for the stateful control plane that manages the lifecycle of flows, queues, and
+//     policies.
+//
+//   - `SaturationDetector`: The interface for a component that provides real-time load signals.
+package contracts
diff --git a/pkg/epp/flowcontrol/contracts/errors.go b/pkg/epp/flowcontrol/contracts/errors.go
index fd46ec7..beb758f 100644
--- a/pkg/epp/flowcontrol/contracts/errors.go
+++ b/pkg/epp/flowcontrol/contracts/errors.go
@@ -18,18 +18,23 @@ package contracts
 
 import "errors"
 
-// Registry Errors
 var (
-	// ErrFlowInstanceNotFound indicates that a requested flow instance (a `ManagedQueue`) does not exist in the registry
-	// shard, either because the flow is not registered or the specific instance (e.g., a draining queue at a particular
-	// priority) is not present.
+	// ErrFlowInstanceNotFound indicates that a requested flow instance (a `ManagedQueue`) does not exist.
 	ErrFlowInstanceNotFound = errors.New("flow instance not found")
 
-	// ErrPriorityBandNotFound indicates that a requested priority band does not exist in the registry because it was not
-	// part of the initial configuration.
+	// ErrFlowIDEmpty indicates that a flow specification was provided with an empty flow ID.
+	ErrFlowIDEmpty = errors.New("flow ID cannot be empty")
+
+	// ErrPriorityBandNotFound indicates that a requested priority band does not exist in the registry configuration.
 	ErrPriorityBandNotFound = errors.New("priority band not found")
 
-	// ErrPolicyQueueIncompatible indicates that a selected policy is not compatible with the capabilities of the queue it
-	// is intended to operate on. For example, a policy requiring priority-based peeking is used with a simple FIFO queue.
+	// ErrPolicyQueueIncompatible indicates that a selected policy is not compatible with the capabilities of the queue.
 	ErrPolicyQueueIncompatible = errors.New("policy is not compatible with queue capabilities")
+
+	// ErrInvalidShardCount indicates that an invalid shard count was provided (e.g., zero or negative).
+	ErrInvalidShardCount = errors.New("invalid shard count")
+
+	// ErrShardDraining indicates that an operation could not be completed because the target shard is in the process of
+	// being gracefully drained. The caller should retry the operation on a different, Active shard.
+	ErrShardDraining = errors.New("shard is draining")
 )
diff --git a/pkg/epp/flowcontrol/contracts/mocks/mocks.go b/pkg/epp/flowcontrol/contracts/mocks/mocks.go
index c5c8d2e..10f093b 100644
--- a/pkg/epp/flowcontrol/contracts/mocks/mocks.go
+++ b/pkg/epp/flowcontrol/contracts/mocks/mocks.go
@@ -34,6 +34,7 @@ import (
 	"fmt"
 	"sync"
 
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
@@ -48,9 +49,9 @@ type MockRegistryShard struct {
 	IsActiveFunc                 func() bool
 	ManagedQueueFunc             func(key types.FlowKey) (contracts.ManagedQueue, error)
 	IntraFlowDispatchPolicyFunc  func(key types.FlowKey) (framework.IntraFlowDispatchPolicy, error)
-	InterFlowDispatchPolicyFunc  func(priority uint) (framework.InterFlowDispatchPolicy, error)
-	PriorityBandAccessorFunc     func(priority uint) (framework.PriorityBandAccessor, error)
-	AllOrderedPriorityLevelsFunc func() []uint
+	InterFlowDispatchPolicyFunc  func(priority int) (framework.InterFlowDispatchPolicy, error)
+	PriorityBandAccessorFunc     func(priority int) (framework.PriorityBandAccessor, error)
+	AllOrderedPriorityLevelsFunc func() []int
 	StatsFunc                    func() contracts.ShardStats
 }
 
@@ -82,21 +83,21 @@ func (m *MockRegistryShard) IntraFlowDispatchPolicy(key types.FlowKey) (framewor
 	return nil, nil
 }
 
-func (m *MockRegistryShard) InterFlowDispatchPolicy(priority uint) (framework.InterFlowDispatchPolicy, error) {
+func (m *MockRegistryShard) InterFlowDispatchPolicy(priority int) (framework.InterFlowDispatchPolicy, error) {
 	if m.InterFlowDispatchPolicyFunc != nil {
 		return m.InterFlowDispatchPolicyFunc(priority)
 	}
 	return nil, nil
 }
 
-func (m *MockRegistryShard) PriorityBandAccessor(priority uint) (framework.PriorityBandAccessor, error) {
+func (m *MockRegistryShard) PriorityBandAccessor(priority int) (framework.PriorityBandAccessor, error) {
 	if m.PriorityBandAccessorFunc != nil {
 		return m.PriorityBandAccessorFunc(priority)
 	}
 	return nil, nil
 }
 
-func (m *MockRegistryShard) AllOrderedPriorityLevels() []uint {
+func (m *MockRegistryShard) AllOrderedPriorityLevels() []int {
 	if m.AllOrderedPriorityLevelsFunc != nil {
 		return m.AllOrderedPriorityLevelsFunc()
 	}
@@ -112,12 +113,12 @@ func (m *MockRegistryShard) Stats() contracts.ShardStats {
 
 // MockSaturationDetector is a simple "stub-style" mock for testing.
 type MockSaturationDetector struct {
-	IsSaturatedFunc func(ctx context.Context) bool
+	IsSaturatedFunc func(ctx context.Context, candidatePods []metrics.PodMetrics) bool
 }
 
-func (m *MockSaturationDetector) IsSaturated(ctx context.Context) bool {
+func (m *MockSaturationDetector) IsSaturated(ctx context.Context, candidatePods []metrics.PodMetrics) bool {
 	if m.IsSaturatedFunc != nil {
-		return m.IsSaturatedFunc(ctx)
+		return m.IsSaturatedFunc(ctx, candidatePods)
 	}
 	return false
 }
diff --git a/pkg/epp/flowcontrol/contracts/registry.go b/pkg/epp/flowcontrol/contracts/registry.go
index b823ae0..fe0b790 100644
--- a/pkg/epp/flowcontrol/contracts/registry.go
+++ b/pkg/epp/flowcontrol/contracts/registry.go
@@ -14,12 +14,6 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package contracts defines the service interfaces that decouple the core `controller.FlowController` engine from its
-// primary dependencies. In alignment with a "Ports and Adapters" (or "Hexagonal") architectural style, these
-// interfaces represent the "ports" through which the engine communicates.
-//
-// This package contains the primary service contracts for the Flow Registry, which acts as the control plane for all
-// flow state and configuration.
 package contracts
 
 import (
@@ -27,14 +21,82 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
 )
 
-// RegistryShard defines the read-oriented interface that a `controller.FlowController` worker uses to access its
-// specific slice (shard) of the `FlowRegistry's` state. It provides a concurrent-safe view of all flow instances, which
-// are uniquely identified by their composite `types.FlowKey`. It is the primary contract for performing dispatch
-// operations.
+// FlowRegistry is the complete interface for the global flow control plane.
+// It composes all role-based interfaces. A concrete implementation of this interface is the single source of truth for
+// all flow control state.
 //
-// # Conformance
+// # Conformance: Implementations MUST be goroutine-safe.
+//
+// # Flow Lifecycle
+//
+// A flow instance, identified by its immutable `types.FlowKey`, has a lease-based lifecycle managed by this interface.
+// Any implementation MUST adhere to this lifecycle:
 //
-// All methods MUST be goroutine-safe.
+//  1. Lease Acquisition: A client calls Connect to acquire a lease. This signals that the flow is in use and protects
+//     it from garbage collection. If the flow does not exist, it is created Just-In-Time (JIT).
+//  2. Active State: A flow is "Active" as long as its lease count is greater than zero.
+//  3. Lease Release: The client MUST call `Close()` on the returned `FlowConnection` to release the lease.
+//     When the lease count drops to zero, the flow becomes "Idle".
+//  4. Garbage Collection: The implementation MUST automatically garbage collect a flow after it has remained
+//     continuously Idle for a configurable duration.
+//
+// # System Invariants
+//
+// Concrete implementations MUST uphold the following invariants:
+//
+//  1. Shard Consistency: All configured priority bands and registered flow instances must exist on every Active shard.
+//  2. Capacity Partitioning: Global and per-band capacity limits must be uniformly partitioned across all Active
+//     shards.
+type FlowRegistry interface {
+	FlowRegistryObserver
+	FlowRegistryDataPlane
+}
+
+// FlowRegistryObserver defines the read-only, observation interface for the registry.
+type FlowRegistryObserver interface {
+	// Stats returns a near-consistent snapshot globally aggregated statistics for the entire `FlowRegistry`.
+	Stats() AggregateStats
+
+	// ShardStats returns a near-consistent slice of statistics snapshots, one for each `RegistryShard`.
+	ShardStats() []ShardStats
+}
+
+// FlowRegistryDataPlane defines the high-throughput, request-path interface for the registry.
+type FlowRegistryDataPlane interface {
+	// WithConnection manages a scoped, leased session for a given flow.
+	// It is the primary and sole entry point for interacting with the data path.
+	//
+	// This method handles the entire lifecycle of a flow connection:
+	// 1. Just-In-Time (JIT) Registration: If the flow for the given `types.FlowKey` does not exist, it is created and
+	//    registered automatically.
+	// 2. Lease Acquisition: It acquires a lifecycle lease, protecting the flow from garbage collection.
+	// 3. Callback Execution: It invokes the provided function `fn`, passing in a temporary `ActiveFlowConnection` handle.
+	// 4. Guaranteed Lease Release: It ensures the lease is safely released when the callback function returns.
+	//
+	// This functional, callback-based approach makes resource leaks impossible, as the caller is not responsible for
+	// manually closing the connection.
+	//
+	// Errors returned by the callback `fn` are propagated up.
+	// Returns `ErrFlowIDEmpty` if the provided key has an empty ID.
+	WithConnection(key types.FlowKey, fn func(conn ActiveFlowConnection) error) error
+}
+
+// ActiveFlowConnection represents a handle to a temporary, leased session on a flow.
+// It provides a safe, scoped entry point to the registry's sharded data plane.
+//
+// An `ActiveFlowConnection` instance is only valid for the duration of the `WithConnection` callback from which it was
+// received. Callers MUST NOT store a reference to this object or use it after the callback returns.
+// Its purpose is to ensure that any interaction with the flow's state (e.g., accessing its shards and queues) occurs
+// safely while the flow is guaranteed to be protected from garbage collection.
+type ActiveFlowConnection interface {
+	// ActiveShards returns a stable snapshot of accessors for all Active internal state shards.
+	ActiveShards() []RegistryShard
+}
+
+// RegistryShard defines the interface for a single slice (shard) of the `FlowRegistry`'s state.
+// A shard acts as an independent, parallel execution unit, allowing the system's dispatch logic to scale horizontally.
+//
+// # Conformance: Implementations MUST be goroutine-safe.
 type RegistryShard interface {
 	// ID returns a unique identifier for this shard, which must remain stable for the shard's lifetime.
 	ID() string
@@ -46,12 +108,12 @@ type RegistryShard interface {
 	// ManagedQueue retrieves the managed queue for the given, unique `types.FlowKey`. This is the primary method for
 	// accessing a specific flow's queue for either enqueueing or dispatching requests.
 	//
-	// Returns an error wrapping `ErrPriorityBandNotFound` if the priority specified in the key is not configured, or
+	// Returns an error wrapping `ErrPriorityBandNotFound` if the priority specified in the `key` is not configured, or
 	// `ErrFlowInstanceNotFound` if no instance exists for the given `key`.
 	ManagedQueue(key types.FlowKey) (ManagedQueue, error)
 
 	// IntraFlowDispatchPolicy retrieves a flow's configured `framework.IntraFlowDispatchPolicy` for this shard,
-	// identified by its unique `FlowKey`.
+	// identified by its unique `types.FlowKey`.
 	// The registry guarantees that a non-nil default policy (as configured at the priority-band level) is returned if
 	// none is specified for the flow.
 	// Returns an error wrapping `ErrFlowInstanceNotFound` if the flow instance does not exist.
@@ -60,46 +122,65 @@ type RegistryShard interface {
 	// InterFlowDispatchPolicy retrieves a priority band's configured `framework.InterFlowDispatchPolicy` for this shard.
 	// The registry guarantees that a non-nil default policy is returned if none is configured for the band.
 	// Returns an error wrapping `ErrPriorityBandNotFound` if the priority level is not configured.
-	InterFlowDispatchPolicy(priority uint) (framework.InterFlowDispatchPolicy, error)
+	InterFlowDispatchPolicy(priority int) (framework.InterFlowDispatchPolicy, error)
 
 	// PriorityBandAccessor retrieves a read-only accessor for a given priority level, providing a view of the band's
-	// state as seen by this specific shard. This is the primary entry point for inter-flow dispatch policies that
-	// need to inspect and compare multiple flow queues within the same priority band.
+	// state as seen by this specific shard. This is the primary entry point for inter-flow dispatch policies that need to
+	// inspect and compare multiple flow queues within the same priority band.
 	// Returns an error wrapping `ErrPriorityBandNotFound` if the priority level is not configured.
-	PriorityBandAccessor(priority uint) (framework.PriorityBandAccessor, error)
+	PriorityBandAccessor(priority int) (framework.PriorityBandAccessor, error)
 
-	// AllOrderedPriorityLevels returns all configured priority levels that this shard is aware of, sorted in ascending
-	// numerical order. This order corresponds to highest priority (lowest numeric value) to lowest priority (highest
+	// AllOrderedPriorityLevels returns all configured priority levels that this shard is aware of, sorted in descending
+	// numerical order. This order corresponds to highest priority (highest numeric value) to lowest priority (lowest
 	// numeric value).
 	// The returned slice provides a definitive, ordered list of priority levels for iteration, for example, by a
 	// `controller.FlowController` worker's dispatch loop.
-	AllOrderedPriorityLevels() []uint
+	AllOrderedPriorityLevels() []int
 
-	// Stats returns a snapshot of the statistics for this specific shard.
+	// Stats returns a near consistent snapshot of the shard's state.
 	Stats() ShardStats
 }
 
-// ManagedQueue defines the interface for a flow's queue instance on a specific shard.
-// It wraps an underlying `framework.SafeQueue`, augmenting it with lifecycle validation against the `FlowRegistry` and
-// integrating atomic statistics updates.
+// ManagedQueue defines the interface for a flow's queue on a specific shard.
+// It acts as a stateful decorator around an underlying `framework.SafeQueue`, augmenting it with statistics tracking.
 //
 // # Conformance
 //
-//   - All methods (including those embedded from `framework.SafeQueue`) MUST be goroutine-safe.
-//   - All mutating methods (`Add()`, `Remove()`, `Cleanup()`, `Drain()`) MUST atomically update relevant statistics
-//     (e.g., queue length, byte size).
+//   - Implementations MUST be goroutine-safe.
+//   - All mutating methods MUST ensure that the underlying queue state and the public statistics (`Len`, `ByteSize`)
+//     are updated as a single atomic transaction.
+//   - The `Add` method MUST return an error wrapping `ErrShardDraining` if the queue instance belongs to a parent shard
+//     that is no longer Active.
 type ManagedQueue interface {
 	framework.SafeQueue
 
-	// FlowQueueAccessor returns a read-only, flow-aware accessor for this queue.
-	// This accessor is primarily used by policy plugins to inspect the queue's state in a structured way.
-	//
+	// FlowQueueAccessor returns a read-only, flow-aware accessor for this queue, used by policy plugins.
 	// Conformance: This method MUST NOT return nil.
 	FlowQueueAccessor() framework.FlowQueueAccessor
 }
 
-// ShardStats holds statistics for a single internal shard within the `FlowRegistry`.
+// AggregateStats holds globally aggregated statistics for the entire `FlowRegistry`.
+// It is a read-only data object representing a near-consistent snapshot of the registry's state.
+type AggregateStats struct {
+	// TotalCapacityBytes is the globally configured maximum total byte size limit across all priority bands and shards.
+	TotalCapacityBytes uint64
+	// TotalByteSize is the total byte size of all items currently queued across the entire system.
+	TotalByteSize uint64
+	// TotalLen is the total number of items currently queued across the entire system.
+	TotalLen uint64
+	// PerPriorityBandStats maps each configured priority level to its globally aggregated statistics.
+	PerPriorityBandStats map[int]PriorityBandStats
+}
+
+// ShardStats holds statistics and identifying information for a `RegistryShard` within the `FlowRegistry`.
+// It is a read-only data object representing a near-consistent snapshot of the shard's state.
 type ShardStats struct {
+	// ID is the unique, stable identifier for this shard.
+	ID string
+	// IsActive indicates if the shard was accepting new work at the time this stats snapshot was generated.
+	// A value of `false` means the shard is in the process of being gracefully drained.
+	// Due to the concurrent nature of the system, this state could change immediately after the snapshot is taken.
+	IsActive bool
 	// TotalCapacityBytes is the optional, maximum total byte size limit aggregated across all priority bands within this
 	// shard. Its value represents the globally configured limit for the `FlowRegistry` partitioned for this shard.
 	// The `controller.FlowController` enforces this limit in addition to any per-band capacity limits.
@@ -110,35 +191,23 @@ type ShardStats struct {
 	// TotalLen is the total number of items currently queued across all priority bands within this shard.
 	TotalLen uint64
 	// PerPriorityBandStats maps each configured priority level to its statistics within this shard.
+	// The capacity values within represent this shard's partition of the global band capacity.
 	// The key is the numerical priority level.
 	// All configured priority levels are guaranteed to be represented.
-	PerPriorityBandStats map[uint]PriorityBandStats
-}
-
-// DeepCopy returns a deep copy of the `ShardStats`.
-func (s *ShardStats) DeepCopy() ShardStats {
-	if s == nil {
-		return ShardStats{}
-	}
-	newStats := *s
-	if s.PerPriorityBandStats != nil {
-		newStats.PerPriorityBandStats = make(map[uint]PriorityBandStats, len(s.PerPriorityBandStats))
-		for k, v := range s.PerPriorityBandStats {
-			newStats.PerPriorityBandStats[k] = v.DeepCopy()
-		}
-	}
-	return newStats
+	PerPriorityBandStats map[int]PriorityBandStats
 }
 
 // PriorityBandStats holds aggregated statistics for a single priority band.
+// It is a read-only data object representing a near-consistent snapshot of the priority band's state.
 type PriorityBandStats struct {
 	// Priority is the numerical priority level this struct describes.
-	Priority uint
-	// PriorityName is an optional, human-readable name for the priority level (e.g., "Critical", "Sheddable").
+	Priority int
+	// PriorityName is a human-readable name for the priority band (e.g., "Critical", "Sheddable").
+	// The registry configuration requires this field, so it is guaranteed to be non-empty.
 	PriorityName string
-	// CapacityBytes is the configured maximum total byte size for this priority band, aggregated across all items in
-	// all flow queues within this band. If scoped to a shard, its value represents the configured band limit for the
-	// `FlowRegistry` partitioned for this shard.
+	// CapacityBytes is the configured maximum total byte size for this priority band.
+	// When viewed via `AggregateStats`, this is the global limit. When viewed via `ShardStats`, this is the partitioned
+	// value for that specific shard.
 	// The `controller.FlowController` enforces this limit.
 	// A default non-zero value is guaranteed if not configured.
 	CapacityBytes uint64
@@ -147,11 +216,3 @@ type PriorityBandStats struct {
 	// Len is the total number of items currently queued in this priority band.
 	Len uint64
 }
-
-// DeepCopy returns a deep copy of the `PriorityBandStats`.
-func (s *PriorityBandStats) DeepCopy() PriorityBandStats {
-	if s == nil {
-		return PriorityBandStats{}
-	}
-	return *s
-}
diff --git a/pkg/epp/flowcontrol/contracts/saturationdetector.go b/pkg/epp/flowcontrol/contracts/saturationdetector.go
index 91d2406..15037d5 100644
--- a/pkg/epp/flowcontrol/contracts/saturationdetector.go
+++ b/pkg/epp/flowcontrol/contracts/saturationdetector.go
@@ -16,7 +16,11 @@ limitations under the License.
 
 package contracts
 
-import "context"
+import (
+	"context"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
+)
 
 // SaturationDetector defines the contract for a component that provides real-time load signals to the
 // `controller.FlowController`.
@@ -32,8 +36,8 @@ import "context"
 //
 // Implementations MUST be goroutine-safe.
 type SaturationDetector interface {
-	// IsSaturated returns true if the system's backend resources are considered saturated.
+	// IsSaturated returns true if the system's backend resources are considered saturated for a set of candidate pods.
 	// `controller.FlowController`'s dispatch workers call this method to decide whether to pause or throttle dispatch
 	// operations to prevent overwhelming the backends.
-	IsSaturated(ctx context.Context) bool
+	IsSaturated(ctx context.Context, candidatePods []metrics.PodMetrics) bool
 }
diff --git a/pkg/epp/flowcontrol/controller/config.go b/pkg/epp/flowcontrol/controller/config.go
new file mode 100644
index 0000000..e542c4d
--- /dev/null
+++ b/pkg/epp/flowcontrol/controller/config.go
@@ -0,0 +1,102 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package controller
+
+import (
+	"fmt"
+	"time"
+)
+
+const (
+	// defaultExpiryCleanupInterval is the default frequency for scanning for expired items.
+	defaultExpiryCleanupInterval = 1 * time.Second
+	// defaultProcessorReconciliationInterval is the default frequency for the supervisor loop.
+	defaultProcessorReconciliationInterval = 5 * time.Second
+	// defaultEnqueueChannelBufferSize is the default size of a worker's incoming request buffer.
+	defaultEnqueueChannelBufferSize = 100
+)
+
+// Config holds the configuration for the `FlowController`.
+type Config struct {
+	// DefaultRequestTTL is the default Time-To-Live applied to requests that do not
+	// specify their own TTL hint.
+	// Optional: If zero, no TTL is applied by default and we rely solely on request context cancellation.
+	DefaultRequestTTL time.Duration
+
+	// ExpiryCleanupInterval is the interval at which each shard processor scans its queues for expired items.
+	// Optional: Defaults to `defaultExpiryCleanupInterval` (1 second).
+	ExpiryCleanupInterval time.Duration
+
+	// ProcessorReconciliationInterval is the frequency at which the `FlowController`'s supervisor loop garbage collects
+	// stale workers.
+	// Optional: Defaults to `defaultProcessorReconciliationInterval` (5 seconds).
+	ProcessorReconciliationInterval time.Duration
+
+	// EnqueueChannelBufferSize is the size of the buffered channel that accepts incoming requests for each shard
+	// processor. This buffer acts as a shock absorber, decoupling the high-frequency distributor from the processor's
+	// serial execution loop and allowing the system to handle short bursts of traffic without blocking.
+	// Optional: Defaults to `defaultEnqueueChannelBufferSize` (100).
+	EnqueueChannelBufferSize int
+}
+
+// ValidateAndApplyDefaults checks the global configuration for validity and then creates a new `Config` object,
+// populating any empty fields with system defaults.
+// It does not mutate the receiver.
+func (c *Config) ValidateAndApplyDefaults() (*Config, error) {
+	cfg := c.deepCopy()
+
+	// --- Validation ---
+	if cfg.DefaultRequestTTL < 0 {
+		return nil, fmt.Errorf("DefaultRequestTTL cannot be negative, but got %v", cfg.DefaultRequestTTL)
+	}
+	if cfg.ExpiryCleanupInterval < 0 {
+		return nil, fmt.Errorf("ExpiryCleanupInterval cannot be negative, but got %v", cfg.ExpiryCleanupInterval)
+	}
+	if cfg.ProcessorReconciliationInterval < 0 {
+		return nil, fmt.Errorf("ProcessorReconciliationInterval cannot be negative, but got %v",
+			cfg.ProcessorReconciliationInterval)
+	}
+	if cfg.EnqueueChannelBufferSize < 0 {
+		return nil, fmt.Errorf("EnqueueChannelBufferSize cannot be negative, but got %d", cfg.EnqueueChannelBufferSize)
+	}
+
+	// --- Defaulting ---
+	if cfg.ExpiryCleanupInterval == 0 {
+		cfg.ExpiryCleanupInterval = defaultExpiryCleanupInterval
+	}
+	if cfg.ProcessorReconciliationInterval == 0 {
+		cfg.ProcessorReconciliationInterval = defaultProcessorReconciliationInterval
+	}
+	if cfg.EnqueueChannelBufferSize == 0 {
+		cfg.EnqueueChannelBufferSize = defaultEnqueueChannelBufferSize
+	}
+	return cfg, nil
+}
+
+// deepCopy creates a deep copy of the `Config` object.
+func (c *Config) deepCopy() *Config {
+	if c == nil {
+		return nil
+	}
+	newCfg := &Config{
+		DefaultRequestTTL:               c.DefaultRequestTTL,
+		ExpiryCleanupInterval:           c.ExpiryCleanupInterval,
+		ProcessorReconciliationInterval: c.ProcessorReconciliationInterval,
+		EnqueueChannelBufferSize:        c.EnqueueChannelBufferSize,
+	}
+	return newCfg
+}
diff --git a/pkg/epp/flowcontrol/controller/controller.go b/pkg/epp/flowcontrol/controller/controller.go
new file mode 100644
index 0000000..aeb0bdd
--- /dev/null
+++ b/pkg/epp/flowcontrol/controller/controller.go
@@ -0,0 +1,385 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package controller contains the implementation of the `FlowController` engine.
+//
+// The FlowController is the central processing engine of the Flow Control system. It is a sharded, high-throughput
+// component responsible for managing the lifecycle of all incoming requests. It achieves this by acting as a stateless
+// supervisor that orchestrates a pool of stateful workers (`internal.ShardProcessor`), distributing incoming requests
+// among them using a sophisticated load-balancing algorithm.
+package controller
+
+import (
+	"cmp"
+	"context"
+	"errors"
+	"fmt"
+	"slices"
+	"sync"
+	"time"
+
+	"github.com/go-logr/logr"
+	"k8s.io/utils/clock"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/controller/internal"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
+	logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
+)
+
+// registryClient defines the minimal interface that the `FlowController` needs to interact with the `FlowRegistry`.
+type registryClient interface {
+	contracts.FlowRegistryObserver
+	contracts.FlowRegistryDataPlane
+}
+
+// shardProcessor is the minimal internal interface that the `FlowController` requires from its workers.
+// This abstraction allows for the injection of mock processors during testing.
+type shardProcessor interface {
+	Run(ctx context.Context)
+	Submit(item *internal.FlowItem) error
+	SubmitOrBlock(ctx context.Context, item *internal.FlowItem) error
+}
+
+// shardProcessorFactory defines the signature for a function that creates a `shardProcessor`.
+// This enables dependency injection for testing.
+type shardProcessorFactory func(
+	shard contracts.RegistryShard,
+	saturationDetector contracts.SaturationDetector,
+	clock clock.Clock,
+	expiryCleanupInterval time.Duration,
+	enqueueChannelBufferSize int,
+	logger logr.Logger,
+) shardProcessor
+
+var _ shardProcessor = &internal.ShardProcessor{}
+
+// managedWorker holds the state for a single supervised worker.
+type managedWorker struct {
+	processor shardProcessor
+	cancel    context.CancelFunc
+}
+
+// FlowController is the central, high-throughput engine of the Flow Control system.
+// It is designed as a stateless distributor that orchestrates a pool of stateful workers (`internal.ShardProcessor`),
+// following a "supervisor-worker" pattern.
+//
+// The controller's `Run` loop executes periodically, acting as a garbage collector that keeps the pool of running
+// workers synchronized with the dynamic shard topology of the `FlowRegistry`.
+type FlowController struct {
+	// --- Immutable dependencies (set at construction) ---
+
+	config                Config
+	registry              registryClient
+	saturationDetector    contracts.SaturationDetector
+	clock                 clock.WithTicker
+	logger                logr.Logger
+	shardProcessorFactory shardProcessorFactory
+
+	// --- Lifecycle state ---
+
+	// parentCtx is the root context for the controller's lifecycle, established when `Run` is called.
+	// It is the parent for all long-lived worker goroutines.
+	parentCtx context.Context
+
+	// --- Concurrent state ---
+
+	// workers is a highly concurrent map storing the `managedWorker` for each shard.
+	// It is the controller's source of truth for the worker pool.
+	// The key is the shard ID (`string`), and the value is a `*managedWorker`.
+	workers sync.Map
+
+	wg sync.WaitGroup
+}
+
+// flowControllerOption is a function that applies a configuration change to a `FlowController`.
+// test-only
+type flowControllerOption func(*FlowController)
+
+// NewFlowController creates a new `FlowController` instance.
+func NewFlowController(
+	ctx context.Context,
+	config Config,
+	registry contracts.FlowRegistry,
+	sd contracts.SaturationDetector,
+	logger logr.Logger,
+	opts ...flowControllerOption,
+) (*FlowController, error) {
+	fc := &FlowController{
+		config:             *config.deepCopy(),
+		registry:           registry,
+		saturationDetector: sd,
+		clock:              clock.RealClock{},
+		logger:             logger.WithName("flow-controller"),
+		parentCtx:          ctx,
+	}
+
+	// Use the real shard processor implementation by default.
+	fc.shardProcessorFactory = func(
+		shard contracts.RegistryShard,
+		saturationDetector contracts.SaturationDetector,
+		clock clock.Clock,
+		expiryCleanupInterval time.Duration,
+		enqueueChannelBufferSize int,
+		logger logr.Logger,
+	) shardProcessor {
+		return internal.NewShardProcessor(
+			shard,
+			saturationDetector,
+			clock,
+			expiryCleanupInterval,
+			enqueueChannelBufferSize,
+			logger)
+	}
+
+	for _, opt := range opts {
+		opt(fc)
+	}
+
+	go fc.run(ctx)
+	return fc, nil
+}
+
+// run starts the `FlowController`'s main reconciliation loop.
+// This loop is responsible for garbage collecting workers whose shards no longer exist in the registry.
+// This method blocks until the provided context is cancelled and ALL worker goroutines have fully terminated.
+func (fc *FlowController) run(ctx context.Context) {
+	fc.logger.Info("Starting FlowController reconciliation loop.")
+	defer fc.logger.Info("FlowController reconciliation loop stopped.")
+
+	ticker := fc.clock.NewTicker(fc.config.ProcessorReconciliationInterval)
+	defer ticker.Stop()
+
+	for {
+		select {
+		case <-ctx.Done():
+			fc.shutdown()
+			return
+		case <-ticker.C():
+			fc.reconcileProcessors()
+		}
+	}
+}
+
+// EnqueueAndWait is the primary, synchronous entry point to the Flow Control system. It submits a request and blocks
+// until the request reaches a terminal outcome (dispatched, rejected, or evicted).
+//
+// # Design Rationale: The Synchronous Model
+//
+// This blocking model is deliberately chosen for its simplicity and robustness, especially in the context of Envoy
+// External Processing (`ext_proc`), which operates on a stream-based protocol.
+//
+//   - `ext_proc` Alignment: A single goroutine typically manages the stream for a given HTTP request.
+//     `EnqueueAndWait` fits this perfectly: the request-handling goroutine calls it, blocks, and upon return, has a
+//     definitive outcome to act upon.
+//   - Simplified State Management: The state of a "waiting" request is implicitly managed by the blocked goroutine's
+//     stack and its `context.Context`. The system only needs to signal this specific goroutine to unblock it.
+//   - Direct Backpressure: If queues are full, `EnqueueAndWait` returns an error immediately, providing direct
+//     backpressure to the caller.
+func (fc *FlowController) EnqueueAndWait(req types.FlowControlRequest) (types.QueueOutcome, error) {
+	if req == nil {
+		return types.QueueOutcomeRejectedOther, errors.New("request cannot be nil")
+	}
+	effectiveTTL := req.InitialEffectiveTTL()
+	if effectiveTTL <= 0 {
+		effectiveTTL = fc.config.DefaultRequestTTL
+	}
+	enqueueTime := fc.clock.Now()
+
+	for {
+		select {
+		case <-fc.parentCtx.Done():
+			return types.QueueOutcomeRejectedOther, fmt.Errorf("%w: %w", types.ErrRejected, types.ErrFlowControllerNotRunning)
+		default:
+			// The controller is running, proceed.
+		}
+
+		// We must create a fresh `FlowItem` on each attempt since finalization is idempotent.
+		// However, we use the original, preserved `enqueueTime`.
+		item := internal.NewItem(req, effectiveTTL, enqueueTime)
+		if outcome, err := fc.distributeRequest(item); err != nil {
+			return outcome, fmt.Errorf("%w: %w", types.ErrRejected, err)
+		}
+
+		// Block until the request is finalized (dispatched, rejected, or evicted).
+		// The finalization logic internally monitors for context cancellation and TTL expiry.
+		finalState := <-item.Done()
+		if errors.Is(finalState.Err, contracts.ErrShardDraining) {
+			fc.logger.V(logutil.DEBUG).Info("Shard is draining, retrying request", "requestID", req.ID())
+			// Benign race with the chosen `contracts.RegistryShard` becoming Draining post selection but before the item was
+			// enqueued into its respective `contracts.ManagedQueue`. Simply try again.
+			continue
+		}
+
+		return finalState.Outcome, finalState.Err
+	}
+}
+
+// distributeRequest implements a flow-aware, two-phase "Join-Shortest-Queue-by-Bytes" (JSQ-Bytes) distribution strategy
+// with graceful backpressure. It selects the optimal worker for a given item and attempts to submit it.
+//
+// The algorithm operates as follows:
+//  1. Candidate Selection: It identifies all Active shards for the item's flow and ranks them by the current byte size
+//     of that flow's queue, from least to most loaded.
+//  2. Phase 1 (Non-blocking Fast Failover): It iterates through the ranked candidates and attempts a non-blocking
+//     submission. The first successful submission wins.
+//  3. Phase 2 (Blocking Fallback): If all non-blocking attempts fail, it performs a single blocking submission to the
+//     least-loaded candidate, providing backpressure.
+func (fc *FlowController) distributeRequest(item *internal.FlowItem) (types.QueueOutcome, error) {
+	key := item.OriginalRequest().FlowKey()
+	reqID := item.OriginalRequest().ID()
+	type candidate struct {
+		processor shardProcessor
+		shardID   string
+		byteSize  uint64
+	}
+	var candidates []candidate
+	err := fc.registry.WithConnection(key, func(conn contracts.ActiveFlowConnection) error {
+		shards := conn.ActiveShards()
+		candidates = make([]candidate, len(shards))
+		for i, shard := range shards {
+			worker := fc.getOrStartWorker(shard)
+			mq, err := shard.ManagedQueue(key)
+			if err != nil {
+				panic(fmt.Sprintf("invariant violation: ManagedQueue for leased flow %s failed on shard %s: %v",
+					key, shard.ID(), err))
+			}
+			candidates[i] = candidate{worker.processor, shard.ID(), mq.ByteSize()}
+		}
+		return nil
+	})
+	if err != nil {
+		return types.QueueOutcomeRejectedOther, fmt.Errorf("failed to acquire lease for request %q (flow %s): %w",
+			reqID, key, err)
+	}
+
+	if len(candidates) == 0 {
+		return types.QueueOutcomeRejectedCapacity, fmt.Errorf("no viable Active shards available for request %q (flow %s)",
+			reqID, key)
+	}
+
+	slices.SortFunc(candidates, func(a, b candidate) int {
+		return cmp.Compare(a.byteSize, b.byteSize)
+	})
+
+	// --- Phase 1: Fast, non-blocking failover attempt ---
+	for _, c := range candidates {
+		if err := c.processor.Submit(item); err == nil {
+			return types.QueueOutcomeNotYetFinalized, nil // Success
+		}
+		fc.logger.V(logutil.DEBUG).Info("Processor busy during fast failover, trying next candidate",
+			"shardID", c.shardID, "requestID", reqID)
+	}
+
+	// --- Phase 2: All processors busy. Attempt a single blocking send to the best candidate. ---
+	bestCandidate := candidates[0]
+	fc.logger.V(logutil.DEBUG).Info("All processors busy, attempting blocking submit to best candidate",
+		"shardID", bestCandidate.shardID, "requestID", reqID, "queueByteSize", bestCandidate.byteSize)
+
+	err = bestCandidate.processor.SubmitOrBlock(item.OriginalRequest().Context(), item)
+	if err != nil {
+		// If even the blocking attempt fails (e.g., context cancelled or processor shut down), the request is definitively
+		// rejected.
+		return types.QueueOutcomeRejectedCapacity, fmt.Errorf(
+			"all viable shard processors are at capacity for request %q (flow %s): %w", reqID, key, err)
+	}
+	return types.QueueOutcomeNotYetFinalized, nil
+}
+
+// getOrStartWorker implements the lazy-loading and startup of shard processors.
+// It attempts to retrieve an existing worker for a shard. If one doesn't exist, it constructs a new worker and attempts
+// to register it atomically. The worker's processor goroutine is only started *after* it has successfully been
+// registered, preventing race conditions where multiple goroutines create and start the same worker.
+func (fc *FlowController) getOrStartWorker(shard contracts.RegistryShard) *managedWorker {
+	if w, ok := fc.workers.Load(shard.ID()); ok {
+		return w.(*managedWorker)
+	}
+
+	// Construct a new worker, but do not start its processor goroutine yet.
+	processorCtx, cancel := context.WithCancel(fc.parentCtx)
+	processor := fc.shardProcessorFactory(
+		shard,
+		fc.saturationDetector,
+		fc.clock,
+		fc.config.ExpiryCleanupInterval,
+		fc.config.EnqueueChannelBufferSize,
+		fc.logger.WithValues("shardID", shard.ID()),
+	)
+	newWorker := &managedWorker{
+		processor: processor,
+		cancel:    cancel,
+	}
+
+	// Atomically load or store. This is the critical step for preventing race conditions.
+	actual, loaded := fc.workers.LoadOrStore(shard.ID(), newWorker)
+	if loaded {
+		// Another goroutine beat us to it. The `newWorker` we created was not stored.
+		// We must cancel the context we created for it to prevent a leak, but we do not need to do anything else, as its
+		// processor was never started.
+		cancel()
+		return actual.(*managedWorker)
+	}
+
+	// We won the race. The `newWorker` was successfully stored.
+	// Now, and only now, do we start the processor's long-running goroutine.
+	fc.wg.Add(1)
+	go func() {
+		defer fc.wg.Done()
+		processor.Run(processorCtx)
+	}()
+
+	return newWorker
+}
+
+// reconcileProcessors is the supervisor's core garbage collection loop.
+// It fetches the current list of Active shards from the registry and removes any workers whose corresponding shards
+// have been fully drained and garbage collected by the registry.
+func (fc *FlowController) reconcileProcessors() {
+	stats := fc.registry.ShardStats()
+	shards := make(map[string]struct{}, len(stats)) // `map[shardID] -> isActive`
+	for _, s := range stats {
+		shards[s.ID] = struct{}{}
+	}
+
+	fc.workers.Range(func(key, value any) bool {
+		shardID := key.(string)
+		worker := value.(*managedWorker)
+
+		// GC check: Is the shard no longer in the registry at all?
+		if _, exists := shards[shardID]; !exists {
+			fc.logger.Info("Stale worker detected for GC'd shard, shutting down.", "shardID", shardID)
+			worker.cancel()
+			fc.workers.Delete(shardID)
+		}
+		return true
+	})
+}
+
+// shutdown gracefully terminates all running `shardProcessor` goroutines.
+// It signals all workers to stop and waits for them to complete their shutdown procedures.
+func (fc *FlowController) shutdown() {
+	fc.logger.Info("Shutting down FlowController and all shard processors.")
+	fc.workers.Range(func(key, value any) bool {
+		shardID := key.(string)
+		worker := value.(*managedWorker)
+		fc.logger.V(logutil.VERBOSE).Info("Sending shutdown signal to processor", "shardID", shardID)
+		worker.cancel()
+		return true
+	})
+
+	fc.wg.Wait()
+	fc.logger.Info("All shard processors have shut down.")
+}
diff --git a/pkg/epp/flowcontrol/controller/doc.go b/pkg/epp/flowcontrol/controller/doc.go
index 8c96bbc..4f2620c 100644
--- a/pkg/epp/flowcontrol/controller/doc.go
+++ b/pkg/epp/flowcontrol/controller/doc.go
@@ -18,105 +18,19 @@ limitations under the License.
 //
 // # Overview
 //
-// The `FlowController` is the central processing engine of the flow control system. It is a sharded, high-throughput
-// component responsible for managing the lifecycle of all incoming requests—from initial submission via the synchronous
-// `EnqueueAndWait` method to a terminal outcome (dispatch, rejection, or eviction). It achieves this by orchestrating
-// its dependencies—the `contracts.FlowRegistry`, the pluggable `Policy` framework, and the
-// `contracts.SaturationDetector`—to make continuous, state-aware decisions.
+// The `FlowController` is the central processing engine of the Flow Control system. It acts as a stateless supervisor
+// that orchestrates a pool of stateful workers (`internal.ShardProcessor`), managing the lifecycle of all incoming
+// requests from initial submission to a terminal outcome (dispatch, rejection, or eviction).
 //
-// # Architecture: The Processor-Shard Relationship
+// # Architecture: Supervisor-Worker Pattern
 //
-// The `FlowController` engine is designed around a clear separation of state and execution. This "control plane vs.
-// data plane" separation is key to enabling dynamic, concurrent-safe configuration updates.
+// This package implements a classic "supervisor-worker" pattern to achieve high throughput and dynamic scalability.
 //
-//   - The `contracts.FlowRegistry` is the **control plane**. It is the single source of truth for all configuration.
-//     When an administrative action occurs (e.g., `RegisterOrUpdateFlow`), the `contracts.FlowRegistry` is responsible
-//     for safely applying that change to each of its managed `contracts.RegistryShard` instances.
-//
-//   - The `contracts.RegistryShard` is the **concurrent-safe state port**. It defines the contract for a state store
-//     that holds the `contracts.ManagedQueue` and framework `Policy` instances for a single shard.
-//
-//   - The `internal.ShardProcessor` is the **data plane worker**. It is given a single `contracts.RegistryShard` to
-//     operate on. Its main `dispatchCycle` continuously acquires a read lock on the shard to get a consistent view of
-//     the active queues and policies, and then executes its dispatch logic.
-//
-// This separation is what enables dynamic updates. The `internal.ShardProcessor` is stateless; it simply executes
-// against the state presented by its `contracts.RegistryShard` on each cycle. This allows the control plane
-// (`contracts.FlowRegistry`) to safely change that state in the background.
-//
-// # Architectural Deep Dive: The `EnqueueAndWait` Model
-//
-// A fundamental design choice is the synchronous, blocking `EnqueueAndWait` method. In the context of the Gateway API
-// Inference Extension's Endpoint Picker (EPP), which operates as an Envoy External Processing (`ext_proc`) server, this
-// model is deliberately chosen for its simplicity and robustness.
-//
-//   - Alignment with `ext_proc`: The `ext_proc` protocol is stream-based. A single goroutine within the EPP manages the
-//     stream for a given HTTP request. `EnqueueAndWait` fits this perfectly: the request-handling goroutine calls it,
-//     blocks, and upon return, has the definitive outcome. It can then immediately act on that outcome, maintaining
-//     clear request-goroutine affinity.
-//
-//   - Simplified State Management: The state of a "waiting" request is implicitly managed by the blocked goroutine's
-//     stack and its `context.Context`. The `FlowController` only needs to signal this specific goroutine to unblock it.
-//
-//   - Direct Backpressure: If queues are full, `EnqueueAndWait` returns `types.ErrQueueAtCapacity`. This provides
-//     immediate, direct backpressure to the earliest point of contact.
-//
-// # Architectural Deep Dive: The Sharded Model & JSQ-Bytes
-//
-// The `FlowController` is built on a sharded architecture to enable parallel processing and prevent a central dispatch
-// loop from becoming a bottleneck. The `FlowController` consists of a top-level manager and a pool of independent
-// `internal.ShardProcessor` workers. The `contracts.FlowRegistry` guarantees that every logical flow is represented by
-// a distinct queue instance on every active shard.
-//
-// This architecture trades deterministic global state for high throughput and scalability. The key challenge, and the
-// system's most critical assumption, revolves around ensuring this distributed model can still achieve global fairness
-// objectives.
-//
-// ## The Critical Assumption: Homogeneity Within Flows
-//
-// The effectiveness of the sharded model hinges on a critical assumption: while the system as a whole manages a
-// heterogeneous set of flows, the traffic *within a single logical flow* is assumed to be roughly homogeneous in its
-// characteristics. A logical flow is intended to represent a single workload or tenant; therefore, the most
-// unpredictable variables (effecting decode behavior) are expected to be statistically similar *within* that flow.
-//
-// ## The Hedge: Join the Shortest Queue by Bytes (JSQ-Bytes)
-//
-// To make this assumption as robust as possible, the `FlowController` uses a "Join the Shortest Queue by Bytes
-// (JSQ-Bytes)" algorithm. `ByteSize` is an excellent proxy for the resources the `FlowController` explicitly manages
-// (host memory pressure and queuing capacity) and is also a reasonable proxy for prefill compute time.
-//
-// Crucially, the goal of the distributor is not to perfectly predict backend compute time, but to intelligently balance
-// the load at the controller level. JSQ-Bytes achieves this by:
-//
-//  1. Reflecting True Load: It distributes work based on each shard's current queue size in bytes—a direct measure of
-//     its memory and capacity congestion.
-//
-//  2. Adapting to Congestion: The byte-size of a queue is a real-time signal of a shard's overall congestion. If a
-//     shard is slow (e.g., due to long-decoding downstream requests), its queues will remain full, and JSQ-Bytes will
-//     adaptively steer new work away.
-//
-//  3. Hedging Against Assumption Violations: This adaptive, self-correcting nature makes it a powerful hedge. It
-//     doesn't just distribute; it actively *load balances* based on the most relevant feedback available.
-//
-// # Architectural Deep Dive: Pre-Policy Gating
-//
-// Before policies are invoked, the `internal.ShardProcessor` applies an `internal.BandFilter`. This function determines
-// which flows within a priority band are eligible for a given operation (e.g., dispatch). This pattern is a deliberate
-// architectural choice to decouple the logic of *viability* from the logic of *selection*.
-//
-//   - An `internal.BandFilter` (e.g., the `internal.NewSaturationFilter`) determines if a flow is viable based on
-//     external signals like backend load.
-//   - The `framework.InterFlowDispatchPolicy` then selects from among the viable candidates based on its own fairness
-//     logic.
-//
-// This abstraction provides two major benefits:
-//
-//  1. Low Contributor Burden: It makes the mental model for policy contributors significantly simpler. An author of a
-//     new fairness policy does not need to be concerned with the complexities of saturation detection or other gating
-//     concerns. They are given a simple, pre-filtered view of the world and can focus solely on their selection logic.
-//
-//  2. Correctness by Construction: The `internal.subsetPriorityBandAccessor` wrapper guarantees that a policy operates
-//     on a consistent, filtered view, regardless of which accessor method it calls (`FlowIDs`, `Queue`, etc.). This
-//     prevents an entire class of subtle bugs where a policy might otherwise see a stale or unfiltered view of the
-//     system state.
+//   - The `FlowController` (Supervisor): The public-facing API of the system. Its primary responsibilities are to
+//     execute a distribution algorithm to select the optimal worker for a new request and to manage the lifecycle of
+//     the worker pool, ensuring it stays synchronized with the underlying shard topology defined by the
+//     `contracts.FlowRegistry`.
+//   - The `internal.ShardProcessor` (Worker): A stateful, single-goroutine actor responsible for the entire lifecycle
+//     of requests on a single shard. The supervisor manages a pool of these workers, one for each
+//     `contracts.RegistryShard`.
 package controller
diff --git a/pkg/epp/flowcontrol/controller/internal/doc.go b/pkg/epp/flowcontrol/controller/internal/doc.go
index 3f39b57..0836546 100644
--- a/pkg/epp/flowcontrol/controller/internal/doc.go
+++ b/pkg/epp/flowcontrol/controller/internal/doc.go
@@ -14,34 +14,19 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package internal provides the core worker implementation for the `controller.FlowController`.
+// Package internal provides the core worker implementation for the controller.FlowController.
 //
-// The components in this package are the private, internal building blocks of the `controller` package. This separation
-// enforces a clean public API at the `controller` level and allows the internal mechanics of the engine to evolve
-// independently.
+// The components in this package are the private, internal building blocks of the controller. This separation enforces
+// a clean public API at the `controller` level and allows the internal mechanics of the engine to evolve independently.
 //
-// # Design Philosophy: A Single-Writer Actor Model
+// # Design Philosophy: The Single-Writer Actor Model
 //
-// The concurrency model for this package is deliberately built around a single-writer, channel-based actor pattern, as
-// implemented in the `ShardProcessor`. While a simple lock-based approach might seem easier, it is insufficient for the
-// system's requirements. The "enqueue" operation is a complex, stateful transaction that requires a **hierarchical
-// capacity check** against both the overall shard and a request's specific priority band.
+// The concurrency model for this package is built around a single-writer, channel-based actor pattern, as implemented
+// in the `ShardProcessor`. All state-mutating operations for a given shard (primarily enqueuing new requests) are
+// funneled through a single "Run" goroutine.
 //
-// A coarse, shard-wide lock would be required to make this transaction atomic, creating a major performance bottleneck
-// and causing head-of-line blocking at the top-level `controller.FlowController`. The single-writer model, where all
-// state mutations are funneled through a single goroutine, makes this transaction atomic *without locks*.
-//
-// This design provides two critical benefits:
-//  1. **Decoupling:** The `controller.FlowController` is decoupled via a non-blocking channel send, allowing for much
-//     higher throughput.
-//  2. **Backpressure:** The state of the channel buffer serves as a high-fidelity, real-time backpressure signal,
-//     enabling more intelligent load balancing.
-//
-// # Future-Proofing for Complex Transactions
-//
-// This model's true power is that it provides a robust foundation for future features like **displacement** (a
-// high-priority item evicting lower-priority ones). This is an "all-or-nothing" atomic transaction that is
-// exceptionally difficult to implement correctly in a lock-free or coarse-grained locking model without significant
-// performance penalties. The single-writer model contains the performance cost of such a potentially long transaction
-// to the single `ShardProcessor`, preventing it from blocking the entire `controller.FlowController`.
+// This design makes complex, multi-step transactions (like a hierarchical capacity check against both a shard's total
+// limit and a priority band's limit) inherently atomic without locks. This avoids the performance bottleneck of a
+// coarse, shard-wide lock and allows the top-level `controller.FlowController` to remain decoupled and highly
+// concurrent.
 package internal
diff --git a/pkg/epp/flowcontrol/controller/internal/filter.go b/pkg/epp/flowcontrol/controller/internal/filter.go
deleted file mode 100644
index 0a06692..0000000
--- a/pkg/epp/flowcontrol/controller/internal/filter.go
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-Copyright 2025 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package internal
-
-import (
-	"context"
-
-	"github.com/go-logr/logr"
-
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
-	logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
-)
-
-// BandFilter is a function that acts as a pre-policy gate. It takes a complete view of a priority band and returns a
-// potentially filtered `framework.PriorityBandAccessor` containing only the flows that are viable candidates for a
-// subsequent policy decision. It can also return a boolean signal to pause the entire operation for the band.
-//
-// This abstraction decouples the logic of determining *viability* (e.g., is a flow subject to backpressure?) from the
-// logic of *selection* (e.g., which of the viable flows is the fairest to pick next?). This separation simplifies the
-// mental model for policy authors, who can focus solely on selection logic without needing to account for external
-// gating signals.
-//
-// Because filters are applied before the band is passed to a policy, they are inherently composable. Multiple filters
-// can be chained to apply different viability criteria. For example, a future filter could be developed to temporarily
-// exclude a "misbehaving" flow that is causing repeated errors, quarantining it from policy consideration.
-//
-// A nil returned `PriorityBandAccessor` indicates that no filtering was necessary and the original accessor should be
-// used. This provides a zero-allocation fast path for the common case where no flows are being filtered.
-type BandFilter func(
-	ctx context.Context,
-	band framework.PriorityBandAccessor,
-	logger logr.Logger,
-) (filteredBand framework.PriorityBandAccessor, shouldPause bool)
-
-// NewSaturationFilter creates a `BandFilter` that uses the provided `contracts.SaturationDetector` to determine which
-// flows are dispatchable. This is the standard filter used in the production `FlowController` for the dispatch
-// operation.
-func NewSaturationFilter(sd contracts.SaturationDetector) BandFilter {
-	return func(
-		ctx context.Context,
-		band framework.PriorityBandAccessor,
-		logger logr.Logger,
-	) (framework.PriorityBandAccessor, bool) {
-		// Phase 1: Implement the current global saturation check.
-		if sd.IsSaturated(ctx) {
-			logger.V(logutil.VERBOSE).Info("System saturated, pausing dispatch for this shard.")
-			return nil, true // Pause dispatching for all bands.
-		}
-
-		// Phase 2 (Future): This is where per-flow saturation logic would go.
-		// It would iterate `band`, call `IsSaturated(ctx, flowID)`, and build a filtered map of allowed flows,
-		// then return `newSubsetPriorityBandAccessor(band, allowedFlows)`.
-		// For now, no per-flow filtering is done. Return nil to signal the fast path.
-		return nil, false // Do not pause, and do not filter any flows.
-	}
-}
-
-// subsetPriorityBandAccessor provides a view of a priority band that is restricted to a specific subset of flows.
-// It implements the `framework.PriorityBandAccessor` interface, ensuring that any policy operating on it will only
-// see the allowed flows, regardless of which accessor method is used. This provides correctness by construction.
-//
-// For performance, it pre-computes a slice of the allowed flows at creation time, making subsequent calls to
-// `FlowKeys()` an O(1) operation with zero allocations.
-type subsetPriorityBandAccessor struct {
-	originalAccessor  framework.PriorityBandAccessor
-	allowedFlows      map[types.FlowKey]struct{}
-	allowedFlowsSlice []types.FlowKey
-}
-
-var _ framework.PriorityBandAccessor = &subsetPriorityBandAccessor{}
-
-// newSubsetPriorityBandAccessor creates a new filtered view of a priority band.
-func newSubsetPriorityBandAccessor(original framework.PriorityBandAccessor, allowed []types.FlowKey) *subsetPriorityBandAccessor {
-	// Pre-compute the map for efficient lookups in `Queue()` and `IterateQueues()`.
-	allowedMap := make(map[types.FlowKey]struct{}, len(allowed))
-	for _, k := range allowed {
-		allowedMap[k] = struct{}{}
-	}
-
-	return &subsetPriorityBandAccessor{
-		originalAccessor:  original,
-		allowedFlows:      allowedMap,
-		allowedFlowsSlice: allowed,
-	}
-}
-
-// Priority returns the numerical priority level of this band.
-func (s *subsetPriorityBandAccessor) Priority() uint {
-	return s.originalAccessor.Priority()
-}
-
-// PriorityName returns the human-readable name of this priority band.
-func (s *subsetPriorityBandAccessor) PriorityName() string {
-	return s.originalAccessor.PriorityName()
-}
-
-// FlowKeys returns a slice of the composite `types.FlowKey`s for every flow instance currently active within this
-// priority band that are in the allowed subset.
-// This is an O(1) operation because the slice is pre-computed at creation.
-func (s *subsetPriorityBandAccessor) FlowKeys() []types.FlowKey {
-	return s.allowedFlowsSlice
-}
-
-// Queue returns a `framework.FlowQueueAccessor` for the specified `ID` within this priority band, but only if it is
-// in the allowed subset. This is an O(1) map lookup. If the flow is not in the allowed subset, it returns nil.
-func (s *subsetPriorityBandAccessor) Queue(id string) framework.FlowQueueAccessor {
-	key := types.FlowKey{ID: id, Priority: s.Priority()}
-	if _, ok := s.allowedFlows[key]; !ok {
-		return nil
-	}
-	return s.originalAccessor.Queue(id)
-}
-
-// IterateQueues executes the given `callback` for each `framework.FlowQueueAccessor` in the allowed subset of this
-// priority band. The iteration stops if the callback returns false.
-// This implementation delegates to the original accessor's iterator and applies the filter, which is more robust and
-// efficient than iterating over a pre-computed slice of IDs.
-func (s *subsetPriorityBandAccessor) IterateQueues(callback func(queue framework.FlowQueueAccessor) bool) {
-	s.originalAccessor.IterateQueues(func(queue framework.FlowQueueAccessor) bool {
-		if _, ok := s.allowedFlows[queue.FlowKey()]; ok {
-			// This queue is in the allowed set, so execute the callback.
-			if !callback(queue) {
-				return false // The callback requested to stop, so we stop the outer iteration too.
-			}
-		}
-		return true // Continue iterating over the original set.
-	})
-}
diff --git a/pkg/epp/flowcontrol/controller/internal/item.go b/pkg/epp/flowcontrol/controller/internal/item.go
index 86aeb8a..d5bdaaf 100644
--- a/pkg/epp/flowcontrol/controller/internal/item.go
+++ b/pkg/epp/flowcontrol/controller/internal/item.go
@@ -18,140 +18,96 @@ package internal
 
 import (
 	"sync"
-	"sync/atomic"
 	"time"
 
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
 )
 
-// flowItem is the internal representation of a request managed by the `FlowController`. It implements the
-// `types.QueueItemAccessor` interface, which is the primary view of the item used by queue and policy implementations.
-// It wraps the original `types.FlowControlRequest` and adds metadata for queuing, lifecycle management, and policy
-// interaction.
-//
-// # Concurrency
-//
-// The `finalize` method is the primary point of concurrency concern. It is designed to be atomic and idempotent through
-// the use of `sync.Once`. This guarantees that an item's final outcome can be set exactly once, even if multiple
-// goroutines (e.g., the main dispatch loop and the expiry cleanup loop) race to finalize it. All other fields are set
-// at creation time and are not modified thereafter, making them safe for concurrent access.
-type flowItem struct {
-	// enqueueTime is the timestamp when the item was logically accepted by the `FlowController`.
-	enqueueTime time.Time
-	// effectiveTTL is the actual time-to-live assigned to this item.
-	effectiveTTL time.Duration
-	// originalRequest is the underlying request object.
+// FinalState encapsulates the terminal outcome of a `FlowItem`'s lifecycle.
+// It is sent over the item's `Done()` channel exactly once.
+type FinalState struct {
+	Outcome types.QueueOutcome
+	Err     error
+}
+
+// FlowItem is the internal representation of a request managed by the `FlowController`.
+type FlowItem struct {
+	// --- Immutable fields (set at creation) ---
+
+	enqueueTime     time.Time
+	effectiveTTL    time.Duration
 	originalRequest types.FlowControlRequest
-	// handle is the unique identifier for this item within a specific queue instance.
-	handle types.QueueItemHandle
-
-	// done is closed exactly once when the item is finalized (dispatched or evicted/rejected).
-	done chan struct{}
-	// err stores the final error state if the item was not successfully dispatched.
-	// It is written to exactly once, protected by `onceFinalize`.
-	err atomic.Value // Stores error
-	// outcome stores the final `types.QueueOutcome` of the item's lifecycle.
-	// It is written to exactly once, protected by `onceFinalize`.
-	outcome atomic.Value // Stores `types.QueueOutcome`
+	handle          types.QueueItemHandle
+
+	// --- Finalization state (protected by onceFinalize) ---
+
+	// done is closed exactly once when the item is finalized.
+	// The closing of this channel establishes a "happens-before" memory barrier, guaranteeing that writes to `outcome`
+	// and `err` are visible to any goroutine that has successfully read from `done`.
+	done chan FinalState
+
+	// finalState  is safely visible to any goroutine after it has confirmed the channel is closed.
+	finalState FinalState
+
 	// onceFinalize ensures the `finalize()` logic is idempotent.
 	onceFinalize sync.Once
 }
 
-// ensure flowItem implements the interface.
-var _ types.QueueItemAccessor = &flowItem{}
+// ensure FlowItem implements the interface.
+var _ types.QueueItemAccessor = &FlowItem{}
 
-// NewItem creates a new `flowItem`, which is the internal representation of a request inside the `FlowController`.
-// This constructor is exported so that the parent `controller` package can create items to be passed into the
-// `internal` package's processors. It initializes the item with a "NotYetFinalized" outcome and an open `done` channel.
-func NewItem(req types.FlowControlRequest, effectiveTTL time.Duration, enqueueTime time.Time) *flowItem {
-	fi := &flowItem{
+// NewItem creates a new `FlowItem`.
+func NewItem(req types.FlowControlRequest, effectiveTTL time.Duration, enqueueTime time.Time) *FlowItem {
+	return &FlowItem{
 		enqueueTime:     enqueueTime,
 		effectiveTTL:    effectiveTTL,
 		originalRequest: req,
-		done:            make(chan struct{}),
+		// Buffer to size one, preventing finalizing goroutine (e.g., the dispatcher) from blocking if the waiting
+		// goroutine has already timed out and is no longer reading.
+		done: make(chan FinalState, 1),
 	}
-	// Initialize the outcome to its zero state.
-	fi.outcome.Store(types.QueueOutcomeNotYetFinalized)
-	return fi
 }
 
 // EnqueueTime returns the time the item was logically accepted by the `FlowController` for queuing. This is used as the
 // basis for TTL calculations.
-func (fi *flowItem) EnqueueTime() time.Time { return fi.enqueueTime }
+func (fi *FlowItem) EnqueueTime() time.Time { return fi.enqueueTime }
 
 // EffectiveTTL returns the actual time-to-live assigned to this item by the `FlowController`.
-func (fi *flowItem) EffectiveTTL() time.Duration { return fi.effectiveTTL }
+func (fi *FlowItem) EffectiveTTL() time.Duration { return fi.effectiveTTL }
 
 // OriginalRequest returns the original, underlying `types.FlowControlRequest` object.
-func (fi *flowItem) OriginalRequest() types.FlowControlRequest { return fi.originalRequest }
+func (fi *FlowItem) OriginalRequest() types.FlowControlRequest { return fi.originalRequest }
 
 // Handle returns the `types.QueueItemHandle` that uniquely identifies this item within a specific queue instance. It
 // returns nil if the item has not yet been added to a queue.
-func (fi *flowItem) Handle() types.QueueItemHandle { return fi.handle }
+func (fi *FlowItem) Handle() types.QueueItemHandle { return fi.handle }
 
 // SetHandle associates a `types.QueueItemHandle` with this item. This method is called by a `framework.SafeQueue`
 // implementation immediately after the item is added to the queue.
-func (fi *flowItem) SetHandle(handle types.QueueItemHandle) { fi.handle = handle }
-
-// Done returns a channel that is closed when the item has been finalized (e.g., dispatched or evicted).
-// This is the primary mechanism for consumers to wait for an item's outcome. It is designed to be used in a `select`
-// statement, allowing the caller to simultaneously wait for other events, such as context cancellation.
-//
-// # Example Usage
-//
-//	select {
-//	case <-item.Done():
-//	    outcome, err := item.FinalState()
-//	    // ... handle outcome
-//	case <-ctx.Done():
-//	    // ... handle cancellation
-//	}
-func (fi *flowItem) Done() <-chan struct{} {
-	return fi.done
-}
-
-// FinalState returns the terminal outcome and error for the item.
-//
-// CRITICAL: This method must only be called after the channel returned by `Done()` has been closed. Calling it before
-// the item is finalized may result in a race condition where the final state has not yet been written.
-func (fi *flowItem) FinalState() (types.QueueOutcome, error) {
-	outcomeVal := fi.outcome.Load()
-	errVal := fi.err.Load()
-
-	var finalOutcome types.QueueOutcome
-	if oc, ok := outcomeVal.(types.QueueOutcome); ok {
-		finalOutcome = oc
-	} else {
-		// This case should not happen if finalize is always called correctly, but we default to a safe value.
-		finalOutcome = types.QueueOutcomeNotYetFinalized
-	}
+func (fi *FlowItem) SetHandle(handle types.QueueItemHandle) { fi.handle = handle }
 
-	var finalErr error
-	if e, ok := errVal.(error); ok {
-		finalErr = e
-	}
-	return finalOutcome, finalErr
+// Done returns a channel that is closed when the item has been finalized (e.g., dispatched, rejected, or evicted).
+func (fi *FlowItem) Done() <-chan FinalState {
+	return fi.done
 }
 
-// finalize sets the item's terminal state (`outcome`, `error`) and closes its `done` channel idempotently using
-// `sync.Once`. This is the single, internal point where an item's lifecycle within the `FlowController` concludes.
-func (fi *flowItem) finalize(outcome types.QueueOutcome, err error) {
+// Finalize sets the item's terminal state and signals the waiting goroutine by closing its `done` channel idempotently.
+// This method is idempotent and is the single point where an item's lifecycle concludes.
+// It is intended to be called only by the component that owns the item's lifecycle, such as a `ShardProcessor`.
+func (fi *FlowItem) Finalize(outcome types.QueueOutcome, err error) {
 	fi.onceFinalize.Do(func() {
-		if err != nil {
-			fi.err.Store(err)
-		}
-		fi.outcome.Store(outcome)
+		finalState := FinalState{Outcome: outcome, Err: err}
+		fi.finalState = finalState
+		fi.done <- finalState
 		close(fi.done)
 	})
 }
 
-// isFinalized checks if the item has been finalized without blocking. It is used internally by the `ShardProcessor` as
-// a defensive check to avoid operating on items that have already been completed.
-func (fi *flowItem) isFinalized() bool {
-	select {
-	case <-fi.done:
-		return true
-	default:
-		return false
-	}
+// isFinalized checks if the item has been finalized without blocking or consuming the final state.
+// It is a side-effect-free check used by the `ShardProcessor` as a defensive measure to avoid operating on
+// already-completed items.
+func (fi *FlowItem) isFinalized() bool {
+	// A buffered channel of size 1 can be safely and non-blockingly checked by its length.
+	// If the finalize function has run, it will have sent a value, and the length will be 1.
+	return len(fi.done) > 0
 }
diff --git a/pkg/epp/flowcontrol/controller/internal/processor.go b/pkg/epp/flowcontrol/controller/internal/processor.go
index 7f9c8ee..9b6bb70 100644
--- a/pkg/epp/flowcontrol/controller/internal/processor.go
+++ b/pkg/epp/flowcontrol/controller/internal/processor.go
@@ -26,6 +26,7 @@ import (
 	"time"
 
 	"github.com/go-logr/logr"
+	"k8s.io/utils/clock"
 	"sigs.k8s.io/controller-runtime/pkg/log"
 
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
@@ -34,70 +35,43 @@ import (
 	logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
 )
 
-const (
-	// enqueueChannelBufferSize sets the size of the buffered channel that accepts incoming requests for the shard
-	// processor. This buffer acts as a "shock absorber," decoupling the upstream distributor from the processor's main
-	// loop and allowing the system to handle short, intense bursts of traffic without blocking the distributor.
-	enqueueChannelBufferSize = 100
+// maxCleanupWorkers caps the number of concurrent workers for background cleanup tasks. This prevents a single shard
+// from overwhelming the Go scheduler with too many goroutines.
+const maxCleanupWorkers = 4
 
-	// maxCleanupWorkers caps the number of concurrent workers for background cleanup tasks. This prevents a single shard
-	// from overwhelming the Go scheduler with too many goroutines.
-	maxCleanupWorkers = 4
-)
-
-var (
-	// errInterFlow is a sentinel error for failures during the inter-flow dispatch phase (e.g., a
-	// `framework.InterFlowDispatchPolicy` fails to select a queue).
-	//
-	// Strategy: When this error is encountered, the dispatch cycle aborts processing for the current priority band and
-	// immediately moves to the next, promoting work conservation. A failure in one band should not halt progress in
-	// others.
-	errInterFlow = errors.New("inter-flow policy failure")
-
-	// errIntraFlow is a sentinel error for failures *after* a specific flow's queue has been selected (e.g., a
-	// `framework.IntraFlowDispatchPolicy` fails or a queue `Remove` fails).
-	//
-	// Strategy: When this error is encountered, the dispatch cycle aborts processing for the entire priority band for the
-	// current cycle. This acts as a critical circuit breaker. A stateless inter-flow policy could otherwise repeatedly
-	// select the same problematic queue in a tight loop of failures. Halting the band for one cycle prevents this.
-	errIntraFlow = errors.New("intra-flow operation failure")
-)
+// ErrProcessorBusy is a sentinel error returned by a the processor's `Submit` method.
+// It indicates that the processor's internal buffer is momentarily full and cannot accept new work.
+// This is used as a signal for the `controller.FlowController`'s "fast failover" logic.
+var ErrProcessorBusy = errors.New("shard processor is busy")
 
-// clock defines an interface for getting the current time, allowing for dependency injection in tests.
-type clock interface {
-	Now() time.Time
-}
-
-// ShardProcessor is the core worker of the `controller.FlowController`. It is paired one-to-one with a
-// `contracts.RegistryShard` instance and is responsible for all request lifecycle operations on that shard, including
-// enqueueing, dispatching, and expiry cleanup. It acts as the "data plane" worker that executes against the
-// concurrent-safe state provided by its shard.
-//
-// For a full rationale on the single-writer concurrency model, see the package-level documentation in `doc.go`.
+// ShardProcessor is the core worker of the `controller.FlowController`.
+// It is paired one-to-one with a `contracts.RegistryShard` instance and is responsible for all request lifecycle
+// operations on that shard. It acts as the "data plane" worker that executes against the concurrent-safe state provided
+// by its shard.
 //
-// # Concurrency Guarantees and Race Conditions
+// # Concurrency Model: The Single-Writer Actor
 //
-// This model provides two key guarantees:
+// To ensure correctness and high performance, the processor uses a single-goroutine, actor-based model. The main `Run`
+// loop is the sole "writer" for all state-mutating operations, particularly enqueueing. This makes complex transactions
+// inherently atomic without coarse-grained locks.
 //
-//  1. **Safe Enqueueing**: The `Run` method's goroutine has exclusive ownership of all operations that *add* items to
-//     queues. This makes the "check-then-act" sequence in `enqueue` (calling `hasCapacity` then `managedQ.Add`)
-//     inherently atomic from a writer's perspective, preventing capacity breaches. While the background
-//     `runExpiryCleanup` goroutine can concurrently *remove* items, this is a benign race; a concurrent removal only
-//     creates more available capacity, ensuring the `hasCapacity` check remains valid.
+// # Concurrency Guarantees
 //
-//  2. **Idempotent Finalization**: The primary internal race is between the main `dispatchCycle` and the background
-//     `runExpiryCleanup` goroutine, which might try to finalize the same `flowItem` simultaneously. This race is
-//     resolved by the `flowItem.finalize` method, which uses `sync.Once` to guarantee that only one of these goroutines
-//     can set the item's final state.
+//  1. Safe Enqueueing: The "check-then-act" sequence for capacity is safe because it is only ever performed by the
+//     single `Run` goroutine.
+//  2. Idempotent Finalization: The primary internal race condition is between the main `dispatchCycle` and the
+//     background `runExpiryCleanup` goroutine, both of which might try to finalize an item. This is resolved by the
+//     `FlowItem.Finalize` method, which uses `sync.Once` to guarantee that only the first attempt to finalize an item
+//     succeeds.
 type ShardProcessor struct {
 	shard                 contracts.RegistryShard
-	dispatchFilter        BandFilter
-	clock                 clock
+	saturationDetector    contracts.SaturationDetector
+	clock                 clock.Clock
 	expiryCleanupInterval time.Duration
 	logger                logr.Logger
 
 	// enqueueChan is the entry point for new requests to be processed by this shard's `Run` loop.
-	enqueueChan chan *flowItem
+	enqueueChan chan *FlowItem
 	// wg is used to wait for background tasks like expiry cleanup to complete on shutdown.
 	wg             sync.WaitGroup
 	isShuttingDown atomic.Bool
@@ -107,35 +81,75 @@ type ShardProcessor struct {
 // NewShardProcessor creates a new `ShardProcessor` instance.
 func NewShardProcessor(
 	shard contracts.RegistryShard,
-	dispatchFilter BandFilter,
-	clock clock,
+	saturationDetector contracts.SaturationDetector,
+	clock clock.Clock,
 	expiryCleanupInterval time.Duration,
+	enqueueChannelBufferSize int,
 	logger logr.Logger,
 ) *ShardProcessor {
 	return &ShardProcessor{
 		shard:                 shard,
-		dispatchFilter:        dispatchFilter,
+		saturationDetector:    saturationDetector,
 		clock:                 clock,
 		expiryCleanupInterval: expiryCleanupInterval,
 		logger:                logger,
 		// A buffered channel decouples the processor from the distributor, allowing for a fast, asynchronous handoff of new
 		// requests.
-		enqueueChan: make(chan *flowItem, enqueueChannelBufferSize),
+		enqueueChan: make(chan *FlowItem, enqueueChannelBufferSize),
 	}
 }
 
-// Run is the main operational loop for the shard processor. It must be run as a goroutine.
+// Submit attempts a non-blocking handoff of an item to the processor's internal channel for asynchronous processing.
 //
-// # Loop Strategy: Interleaving Enqueue and Dispatch
+// It returns nil if the item was accepted by the processor, or if the processor is shutting down (in which case the
+// item is immediately finalized with a shutdown error). In both cases, a nil return means the item's lifecycle has been
+// handled by this processor and the caller should not retry.
+// It returns `ErrProcessorBusy` if the processor's channel is momentarily full, signaling that the caller should try
+// another processor.
+func (sp *ShardProcessor) Submit(item *FlowItem) error {
+	if sp.isShuttingDown.Load() {
+		item.Finalize(types.QueueOutcomeRejectedOther,
+			fmt.Errorf("%w: %w", types.ErrRejected, types.ErrFlowControllerNotRunning))
+		return nil // Success from the caller's perspective; the item is terminal.
+	}
+
+	select {
+	case sp.enqueueChan <- item:
+		return nil // Success
+	default:
+		// The channel buffer is full, signaling transient backpressure.
+		return ErrProcessorBusy
+	}
+}
+
+// SubmitOrBlock performs a blocking submission of an item to the processor's internal channel.
+// It will wait until either the submission succeeds or the provided context is cancelled.
 //
-// The loop uses a `select` statement to interleave two primary tasks:
-//  1. Accepting new requests from the `enqueueChan`.
-//  2. Attempting to dispatch existing requests from queues via `dispatchCycle`.
+// This method is the fallback used by the distributor when all processors are busy, providing graceful backpressure
+// instead of immediate rejection.
 //
-// This strategy is crucial for balancing responsiveness and throughput. When a new item arrives, it is immediately
-// enqueued, and a dispatch cycle is triggered. This gives high-priority new arrivals a chance to be dispatched quickly.
-// When no new items are arriving, the loop's `default` case continuously calls `dispatchCycle` to drain the existing
-// backlog, ensuring work continues.
+// It returns the `ctx.Err()` if the context is cancelled during the wait.
+func (sp *ShardProcessor) SubmitOrBlock(ctx context.Context, item *FlowItem) error {
+	if sp.isShuttingDown.Load() {
+		// Here, we return an error because the caller, expecting to block, was prevented from doing so by the shutdown.
+		// This is a failure of the operation.
+		item.Finalize(types.QueueOutcomeRejectedOther,
+			fmt.Errorf("%w: %w", types.ErrRejected, types.ErrFlowControllerNotRunning))
+		return types.ErrFlowControllerNotRunning
+	}
+
+	select {
+	case sp.enqueueChan <- item:
+		return nil // Success
+	case <-ctx.Done():
+		// The caller's context was cancelled while we were blocked.
+		return ctx.Err()
+	}
+}
+
+// Run is the main operational loop for the shard processor. It must be run as a goroutine.
+// It uses a `select` statement to interleave accepting new requests with dispatching existing ones, balancing
+// responsiveness with throughput.
 func (sp *ShardProcessor) Run(ctx context.Context) {
 	sp.logger.V(logutil.DEFAULT).Info("Shard processor run loop starting.")
 	defer sp.logger.V(logutil.DEFAULT).Info("Shard processor run loop stopped.")
@@ -148,10 +162,8 @@ func (sp *ShardProcessor) Run(ctx context.Context) {
 	//
 	//  1. Context Cancellation: The highest priority is shutting down. If the context's `Done` channel is closed, the
 	//     loop will drain all queues and exit. This is the primary exit condition.
-	//
 	//  2. New Item Arrival: If an item is available on `enqueueChan`, it will be processed. This ensures that the
 	//     processor is responsive to new work.
-	//
 	//  3. Default (Dispatch): If neither of the above cases is ready, the `default` case executes, ensuring the loop is
 	//     non-blocking. It continuously attempts to dispatch items from the existing backlog, preventing starvation and
 	//     ensuring queues are drained.
@@ -175,8 +187,9 @@ func (sp *ShardProcessor) Run(ctx context.Context) {
 			sp.enqueue(item)
 			sp.dispatchCycle(ctx)
 		default:
+			// If no new items are arriving, continuously try to dispatch from the backlog.
 			if !sp.dispatchCycle(ctx) {
-				// If no work was done, yield to other goroutines to prevent a tight, busy-loop when idle, but allow for
+				// If no work was done, yield to the scheduler to prevent a tight, busy-loop when idle, while still allowing for
 				// immediate rescheduling.
 				runtime.Gosched()
 			}
@@ -184,20 +197,10 @@ func (sp *ShardProcessor) Run(ctx context.Context) {
 	}
 }
 
-// Enqueue sends a new flow item to the processor's internal channel for asynchronous processing by its main `Run` loop.
-// If the processor is shutting down, it immediately finalizes the item with a shutdown error.
-func (sp *ShardProcessor) Enqueue(item *flowItem) {
-	if sp.isShuttingDown.Load() {
-		item.finalize(types.QueueOutcomeRejectedOther,
-			fmt.Errorf("%w: %w", types.ErrRejected, types.ErrFlowControllerShutdown))
-		return
-	}
-	sp.enqueueChan <- item
-}
-
-// enqueue is the internal implementation for adding a new item to a managed queue. It is always run from the single
-// main `Run` goroutine, making its "check-then-act" logic for capacity safe.
-func (sp *ShardProcessor) enqueue(item *flowItem) {
+// enqueue is responsible for adding a new item to its designated queue. It is always run from the single main `Run`
+// goroutine, which makes its multi-step "check-then-act" logic for capacity management inherently atomic and safe from
+// race conditions.
+func (sp *ShardProcessor) enqueue(item *FlowItem) {
 	req := item.OriginalRequest()
 	key := req.FlowKey()
 
@@ -213,7 +216,7 @@ func (sp *ShardProcessor) enqueue(item *flowItem) {
 	if err != nil {
 		finalErr := fmt.Errorf("configuration error: failed to get queue for flow key %s: %w", key, err)
 		logger.Error(finalErr, "Rejecting item.")
-		item.finalize(types.QueueOutcomeRejectedOther, fmt.Errorf("%w: %w", types.ErrRejected, finalErr))
+		item.Finalize(types.QueueOutcomeRejectedOther, fmt.Errorf("%w: %w", types.ErrRejected, finalErr))
 		return
 	}
 
@@ -221,7 +224,7 @@ func (sp *ShardProcessor) enqueue(item *flowItem) {
 	if err != nil {
 		finalErr := fmt.Errorf("configuration error: failed to get priority band for priority %d: %w", key.Priority, err)
 		logger.Error(finalErr, "Rejecting item.")
-		item.finalize(types.QueueOutcomeRejectedOther, fmt.Errorf("%w: %w", types.ErrRejected, finalErr))
+		item.Finalize(types.QueueOutcomeRejectedOther, fmt.Errorf("%w: %w", types.ErrRejected, finalErr))
 		return
 	}
 	logger = logger.WithValues("priorityName", band.PriorityName())
@@ -237,7 +240,7 @@ func (sp *ShardProcessor) enqueue(item *flowItem) {
 			"bandTotalBytes", bandStats.ByteSize,
 			"bandCapacityBytes", bandStats.CapacityBytes,
 		)
-		item.finalize(types.QueueOutcomeRejectedCapacity, fmt.Errorf("%w: %w", types.ErrRejected, types.ErrQueueAtCapacity))
+		item.Finalize(types.QueueOutcomeRejectedCapacity, fmt.Errorf("%w: %w", types.ErrRejected, types.ErrQueueAtCapacity))
 		return
 	}
 
@@ -250,7 +253,8 @@ func (sp *ShardProcessor) enqueue(item *flowItem) {
 	//  2. The background `runExpiryCleanup` goroutine acts as the ultimate guarantor of correctness, as it will
 	//     eventually find and evict any finalized item that slips through this check and is added to a queue.
 	if item.isFinalized() {
-		outcome, err := item.FinalState()
+		finalState := item.finalState
+		outcome, err := finalState.Outcome, finalState.Err
 		logger.V(logutil.VERBOSE).Info("Item finalized before adding to queue, ignoring.", "outcome", outcome, "err", err)
 		return
 	}
@@ -260,15 +264,15 @@ func (sp *ShardProcessor) enqueue(item *flowItem) {
 	if err := managedQ.Add(item); err != nil {
 		finalErr := fmt.Errorf("failed to add item to queue for flow key %s: %w", key, err)
 		logger.Error(finalErr, "Rejecting item.")
-		item.finalize(types.QueueOutcomeRejectedOther, fmt.Errorf("%w: %w", types.ErrRejected, finalErr))
+		item.Finalize(types.QueueOutcomeRejectedOther, fmt.Errorf("%w: %w", types.ErrRejected, finalErr))
 		return
 	}
 	logger.V(logutil.TRACE).Info("Item enqueued.")
 }
 
 // hasCapacity checks if the shard and the specific priority band have enough capacity to accommodate an item of a given
-// size.
-func (sp *ShardProcessor) hasCapacity(priority uint, itemByteSize uint64) bool {
+// size. This check is only safe because it is called from the single-writer `enqueue` method.
+func (sp *ShardProcessor) hasCapacity(priority int, itemByteSize uint64) bool {
 	if itemByteSize == 0 {
 		return true
 	}
@@ -288,26 +292,29 @@ func (sp *ShardProcessor) hasCapacity(priority uint, itemByteSize uint64) bool {
 // It applies the configured policies for each band to select an item and then attempts to dispatch it.
 // It returns true if an item was successfully dispatched, and false otherwise.
 //
-// # Error Handling Philosophy
+// # Error Handling Philosophy: Failure Isolation & Work Conservation
+//
+// A problem in one priority band (e.g., a failing policy) must not halt processing for other, healthy bands.
+// Therefore, any error during selection or dispatch for a given band is logged, and the processor immediately continues
+// to the next-lower priority band to maximize system throughput.
+//
+// # Strict Policy Adherence vs. Work Conservation
 //
-// The engine employs a robust, two-tiered error handling strategy to isolate failures and maximize system availability.
-// This is managed via the `errInterFlow` and `errIntraFlow` sentinel errors.
+// This function's logic strictly adheres to the scheduling decisions made by the configured policies, even at the cost
+// of work conservation. After the inter-flow (fairness) and intra-flow (ordering) policies select a request (e.g.,
+// `A_1` from flow `A`), a post-selection viability check is performed.
 //
-//   - Inter-Flow Failures: If a failure occurs while selecting a flow (e.g., the `InterFlowDispatchPolicy` fails), the
-//     processor aborts the *current priority band* and immediately moves to the next one. This promotes work
-//     conservation, ensuring a single misconfigured band does not halt progress for the entire system.
+// If request `A_1` targets saturated backends, this function will stop the entire dispatch cycle for the current tick.
+// It will NOT attempt to find other work (like request `B_1` or `A_2`). Instead, it respects the policy decision that
+// `A_1` is next and enforces Head-of-Line blocking on it.
 //
-//   - Intra-Flow Failures: If a failure occurs *after* a flow has been selected (e.g., the `IntraFlowDispatchPolicy`
-//     fails), the processor aborts the *entire priority band* for the current cycle. This is a critical circuit
-//     breaker. An inter-flow policy that is not stateful with respect to past failures could otherwise repeatedly
-//     select the same problematic queue, causing a tight loop of failures. Halting the band for one cycle prevents
-//     this.
+// # Future Extension Point
+//
+// The iteration over priority bands is currently a simple, strict-priority loop. This could be abstracted into a third
+// policy tier (e.g., an `InterBandDispatchPolicy`) if more complex scheduling between bands, such as Weighted Fair
+// Queuing (WFQ), is ever required.
 func (sp *ShardProcessor) dispatchCycle(ctx context.Context) bool {
 	baseLogger := sp.logger.WithName("dispatchCycle")
-
-	// FUTURE EXTENSION POINT: The iteration over priority bands is currently a simple, strict-priority loop.
-	// This could be abstracted into a third policy tier (e.g., an `InterBandDispatchPolicy`) if more complex scheduling
-	// between bands, such as Weighted Fair Queuing (WFQ), is ever required. For now, strict priority is sufficient.
 	for _, priority := range sp.shard.AllOrderedPriorityLevels() {
 		originalBand, err := sp.shard.PriorityBandAccessor(priority)
 		if err != nil {
@@ -316,32 +323,16 @@ func (sp *ShardProcessor) dispatchCycle(ctx context.Context) bool {
 		}
 		logger := baseLogger.WithValues("priority", priority, "priorityName", originalBand.PriorityName())
 
-		// Apply the configured filter to get a view of only the dispatchable flows.
-		dispatchableBand, shouldPause := sp.dispatchFilter(ctx, originalBand, logger)
-		if shouldPause {
-			return false // A global gate told us to stop the entire cycle.
-		}
-		if dispatchableBand == nil {
-			// A nil return from the filter indicates the fast path: no filtering was needed.
-			dispatchableBand = originalBand
-		}
-
-		// Pass the (potentially filtered) band to the policies.
-		item, err := sp.selectItem(dispatchableBand, logger)
+		item, err := sp.selectItem(originalBand, logger)
 		if err != nil {
-			// The error handling strategy depends on the type of failure (inter- vs. intra-flow).
-			if errors.Is(err, errIntraFlow) {
-				logger.Error(err, "Intra-flow policy failure, skipping priority band for this cycle")
-			} else {
-				logger.Error(err, "Inter-flow policy or configuration failure, skipping priority band for this cycle")
-			}
+			logger.Error(err, "Failed to select item, skipping priority band for this cycle")
 			continue
 		}
 		if item == nil {
-			// This is the common case where a priority band has no items to dispatch.
 			logger.V(logutil.TRACE).Info("No item selected by dispatch policies, skipping band")
 			continue
 		}
+
 		logger = logger.WithValues(
 			"flowKey", item.OriginalRequest().FlowKey(),
 			"flowID", item.OriginalRequest().FlowKey().ID,
@@ -349,15 +340,18 @@ func (sp *ShardProcessor) dispatchCycle(ctx context.Context) bool {
 			"reqID", item.OriginalRequest().ID(),
 			"reqByteSize", item.OriginalRequest().ByteSize())
 
+		candidatePods := item.OriginalRequest().CandidatePodsForScheduling()
+		if sp.saturationDetector.IsSaturated(ctx, candidatePods) {
+			logger.V(logutil.VERBOSE).Info("Policy's chosen item is for a saturated flow; pausing dispatch and blocking on HoL")
+			return false
+		}
+
 		if err := sp.dispatchItem(item, logger); err != nil {
-			// All errors from dispatchItem are considered intra-flow and unrecoverable for this band in this cycle.
 			logger.Error(err, "Failed to dispatch item, skipping priority band for this cycle")
 			continue
 		}
-		// A successful dispatch occurred, so we return true to signal that work was done.
 		return true
 	}
-	// No items were dispatched in this cycle across all priority bands.
 	return false
 }
 
@@ -369,12 +363,11 @@ func (sp *ShardProcessor) selectItem(
 ) (types.QueueItemAccessor, error) {
 	interP, err := sp.shard.InterFlowDispatchPolicy(band.Priority())
 	if err != nil {
-		return nil, fmt.Errorf("%w: could not get InterFlowDispatchPolicy: %w", errInterFlow, err)
+		return nil, fmt.Errorf("could not get InterFlowDispatchPolicy: %w", err)
 	}
 	queue, err := interP.SelectQueue(band)
 	if err != nil {
-		return nil, fmt.Errorf("%w: InterFlowDispatchPolicy %q failed to select queue: %w",
-			errInterFlow, interP.Name(), err)
+		return nil, fmt.Errorf("InterFlowDispatchPolicy %q failed to select queue: %w", interP.Name(), err)
 	}
 	if queue == nil {
 		logger.V(logutil.TRACE).Info("No queue selected by InterFlowDispatchPolicy")
@@ -387,13 +380,11 @@ func (sp *ShardProcessor) selectItem(
 		"selectedFlowPriority", key.Priority)
 	intraP, err := sp.shard.IntraFlowDispatchPolicy(key)
 	if err != nil {
-		// This is an intra-flow failure because we have already successfully selected a queue.
-		return nil, fmt.Errorf("%w: could not get IntraFlowDispatchPolicy for flow %q: %w", errIntraFlow, key, err)
+		return nil, fmt.Errorf("could not get IntraFlowDispatchPolicy for flow %s: %w", key, err)
 	}
 	item, err := intraP.SelectItem(queue)
 	if err != nil {
-		return nil, fmt.Errorf("%w: IntraFlowDispatchPolicy %q failed to select item for flow %q: %w",
-			errIntraFlow, intraP.Name(), key, err)
+		return nil, fmt.Errorf("IntraFlowDispatchPolicy %q failed to select item for flow %s: %w", intraP.Name(), key, err)
 	}
 	if item == nil {
 		logger.V(logutil.TRACE).Info("No item selected by IntraFlowDispatchPolicy")
@@ -403,7 +394,7 @@ func (sp *ShardProcessor) selectItem(
 }
 
 // dispatchItem handles the final steps of dispatching an item after it has been selected by policies. This includes
-// removing it from its queue, checking for last-minute expiry, and finalizing its outcome.
+// removing it from its queue and finalizing its outcome.
 func (sp *ShardProcessor) dispatchItem(itemAcc types.QueueItemAccessor, logger logr.Logger) error {
 	logger = logger.WithName("dispatchItem")
 
@@ -411,7 +402,7 @@ func (sp *ShardProcessor) dispatchItem(itemAcc types.QueueItemAccessor, logger l
 	// We must look up the queue by its specific priority, as a flow might have draining queues at other levels.
 	managedQ, err := sp.shard.ManagedQueue(req.FlowKey())
 	if err != nil {
-		return fmt.Errorf("%w: failed to get ManagedQueue for flow %q: %w", errIntraFlow, req.FlowKey(), err)
+		return fmt.Errorf("failed to get ManagedQueue for flow %s: %w", req.FlowKey(), err)
 	}
 
 	// The core mutation: remove the item from the queue.
@@ -420,21 +411,11 @@ func (sp *ShardProcessor) dispatchItem(itemAcc types.QueueItemAccessor, logger l
 		// This can happen benignly if the item was already removed by the expiry cleanup loop between the time it was
 		// selected by the policy and the time this function is called.
 		logger.V(logutil.VERBOSE).Info("Item already removed from queue, likely by expiry cleanup", "err", err)
-		return fmt.Errorf("%w: failed to remove item %q from queue for flow %q: %w",
-			errIntraFlow, req.ID(), req.FlowKey(), err)
-	}
-
-	removedItem, ok := removedItemAcc.(*flowItem)
-	if !ok {
-		// This indicates a severe logic error where a queue returns an item of an unexpected type. This violates a
-		// core system invariant: all items managed by the processor must be of type *flowItem. This is an unrecoverable
-		// state for this shard.
-		unexpectedItemErr := fmt.Errorf("%w: internal error: item %q of type %T is not a *flowItem",
-			errIntraFlow, removedItemAcc.OriginalRequest().ID(), removedItemAcc)
-		panic(unexpectedItemErr)
+		return fmt.Errorf("failed to remove item %q from queue for flow %s: %w", req.ID(), req.FlowKey(), err)
 	}
 
 	// Final check for expiry/cancellation right before dispatch.
+	removedItem := removedItemAcc.(*FlowItem)
 	isExpired, outcome, expiryErr := checkItemExpiry(removedItem, sp.clock.Now())
 	if isExpired {
 		// Ensure we always have a non-nil error to wrap for consistent logging and error handling.
@@ -444,43 +425,34 @@ func (sp *ShardProcessor) dispatchItem(itemAcc types.QueueItemAccessor, logger l
 		}
 		logger.V(logutil.VERBOSE).Info("Item expired at time of dispatch, evicting", "outcome", outcome,
 			"err", finalErr)
-		removedItem.finalize(outcome, fmt.Errorf("%w: %w", types.ErrEvicted, finalErr))
+		removedItem.Finalize(outcome, fmt.Errorf("%w: %w", types.ErrEvicted, finalErr))
 		// Return an error to signal that the dispatch did not succeed.
-		return fmt.Errorf("%w: item %q expired before dispatch: %w", errIntraFlow, req.ID(), finalErr)
+		return fmt.Errorf("item %q expired before dispatch: %w", req.ID(), finalErr)
 	}
 
 	// Finalize the item as dispatched.
-	removedItem.finalize(types.QueueOutcomeDispatched, nil)
+	removedItem.Finalize(types.QueueOutcomeDispatched, nil)
 	logger.V(logutil.TRACE).Info("Item dispatched.")
 	return nil
 }
 
-// checkItemExpiry checks if an item has been cancelled (via its context) or has exceeded its TTL. It returns true if
-// the item is expired, along with the corresponding outcome and error.
+// checkItemExpiry provides the authoritative check to determine if an item should be evicted due to TTL expiry or
+// context cancellation.
 //
-// This function provides "defense in depth" against race conditions. It is the authoritative check that is called from
-// multiple locations (the dispatch loop and the cleanup loop) to determine if an item should be evicted. Its first
-// action is to check if the item has *already* been finalized by a competing goroutine, ensuring that the final outcome
-// is decided exactly once.
+// It serves as a safeguard against race conditions. Its first action is to check if the item has already been finalized
+// by a competing goroutine (e.g., the cleanup loop finalizing an item the dispatch loop is trying to process).=
+// This ensures that the final outcome is decided exactly once.
 func checkItemExpiry(
 	itemAcc types.QueueItemAccessor,
 	now time.Time,
 ) (isExpired bool, outcome types.QueueOutcome, err error) {
-	item, ok := itemAcc.(*flowItem)
-	if !ok {
-		// This indicates a severe logic error where a queue returns an item of an unexpected type. This violates a
-		// core system invariant: all items managed by the processor must be of type *flowItem. This is an unrecoverable
-		// state for this shard.
-		unexpectedItemErr := fmt.Errorf("internal error: item %q of type %T is not a *flowItem",
-			itemAcc.OriginalRequest().ID(), itemAcc)
-		panic(unexpectedItemErr)
-	}
+	item := itemAcc.(*FlowItem)
 
 	// This check is a critical defense against race conditions. If another goroutine (e.g., the cleanup loop) has
 	// already finalized this item, we must respect that outcome.
 	if item.isFinalized() {
-		outcome, err := item.FinalState()
-		return true, outcome, err
+		finalState := item.finalState
+		return true, finalState.Outcome, finalState.Err
 	}
 
 	// Check if the request's context has been cancelled.
@@ -517,7 +489,7 @@ func (sp *ShardProcessor) runExpiryCleanup(ctx context.Context) {
 }
 
 // cleanupExpired performs a single scan of all queues on the shard, removing and finalizing any items that have
-// expired due to TTL or context cancellation.
+// expired.
 func (sp *ShardProcessor) cleanupExpired(now time.Time) {
 	processFn := func(managedQ contracts.ManagedQueue, queueLogger logr.Logger) {
 		// This predicate identifies items to be removed by the Cleanup call.
@@ -537,9 +509,8 @@ func (sp *ShardProcessor) cleanupExpired(now time.Time) {
 	sp.processAllQueuesConcurrently("cleanupExpired", processFn)
 }
 
-// shutdown handles the graceful termination of the processor. It uses sync.Once to guarantee that the shutdown logic is
-// executed exactly once, regardless of whether it's triggered by context cancellation or the closing of the enqueue
-// channel.
+// shutdown handles the graceful termination of the processor, ensuring any pending items in the enqueue channel or in
+// the queues are finalized correctly.
 func (sp *ShardProcessor) shutdown() {
 	sp.shutdownOnce.Do(func() {
 		// Set the atomic bool so that any new calls to Enqueue will fail fast.
@@ -555,8 +526,8 @@ func (sp *ShardProcessor) shutdown() {
 				if item == nil { // This is a safeguard against logic errors in the distributor.
 					continue
 				}
-				item.finalize(types.QueueOutcomeRejectedOther,
-					fmt.Errorf("%w: %w", types.ErrRejected, types.ErrFlowControllerShutdown))
+				item.Finalize(types.QueueOutcomeRejectedOther,
+					fmt.Errorf("%w: %w", types.ErrRejected, types.ErrFlowControllerNotRunning))
 			default:
 				// The channel is empty, we can now safely close it.
 				break DrainLoop
@@ -569,8 +540,7 @@ func (sp *ShardProcessor) shutdown() {
 	})
 }
 
-// evictAll drains all queues on the shard and finalizes every item with a shutdown error. This is called when the
-// processor is shutting down to ensure no requests are left in a pending state.
+// evictAll drains all queues on the shard and finalizes every item with a shutdown error.
 func (sp *ShardProcessor) evictAll() {
 	processFn := func(managedQ contracts.ManagedQueue, queueLogger logr.Logger) {
 		removedItems, err := managedQ.Drain()
@@ -580,7 +550,7 @@ func (sp *ShardProcessor) evictAll() {
 
 		// Finalize all the items that were removed.
 		getOutcome := func(_ types.QueueItemAccessor) (types.QueueOutcome, error) {
-			return types.QueueOutcomeEvictedOther, fmt.Errorf("%w: %w", types.ErrEvicted, types.ErrFlowControllerShutdown)
+			return types.QueueOutcomeEvictedOther, fmt.Errorf("%w: %w", types.ErrEvicted, types.ErrFlowControllerNotRunning)
 		}
 		sp.finalizeItems(removedItems, queueLogger, getOutcome)
 	}
@@ -659,23 +629,23 @@ func (sp *ShardProcessor) finalizeItems(
 	getOutcome func(item types.QueueItemAccessor) (types.QueueOutcome, error),
 ) {
 	for _, i := range items {
-		item, ok := i.(*flowItem)
+		item, ok := i.(*FlowItem)
 		if !ok {
-			unexpectedItemErr := fmt.Errorf("internal error: item %q of type %T is not a *flowItem",
+			unexpectedItemErr := fmt.Errorf("internal error: item %q of type %T is not a *FlowItem",
 				i.OriginalRequest().ID(), i)
 			logger.Error(unexpectedItemErr, "Panic condition detected during finalization", "item", i)
 			continue
 		}
 
 		outcome, err := getOutcome(i)
-		item.finalize(outcome, err)
+		item.Finalize(outcome, err)
 		logger.V(logutil.TRACE).Info("Item finalized", "reqID", item.OriginalRequest().ID(),
 			"outcome", outcome, "err", err)
 	}
 }
 
-// finalizeExpiredItems is a specialized version of finalizeItems for items that are known to be expired. It determines
-// the precise reason for expiry and finalizes the item accordingly.
+// finalizeExpiredItems is a specialized version of finalizeItems for items that are known to be expired.
+// It determines the precise reason for expiry and finalizes the item accordingly.
 func (sp *ShardProcessor) finalizeExpiredItems(items []types.QueueItemAccessor, now time.Time, logger logr.Logger) {
 	getOutcome := func(item types.QueueItemAccessor) (types.QueueOutcome, error) {
 		// We don't need the `isExpired` boolean here because we know it's true, but this function conveniently returns the
diff --git a/pkg/epp/flowcontrol/framework/mocks/mocks.go b/pkg/epp/flowcontrol/framework/mocks/mocks.go
index b8715b7..ff8441f 100644
--- a/pkg/epp/flowcontrol/framework/mocks/mocks.go
+++ b/pkg/epp/flowcontrol/framework/mocks/mocks.go
@@ -67,14 +67,14 @@ var _ framework.FlowQueueAccessor = &MockFlowQueueAccessor{}
 // Simple accessors are configured with public value fields (e.g., `PriorityV`).
 // Complex methods with logic are configured with function fields (e.g., `IterateQueuesFunc`).
 type MockPriorityBandAccessor struct {
-	PriorityV         uint
+	PriorityV         int
 	PriorityNameV     string
 	FlowKeysFunc      func() []types.FlowKey
 	QueueFunc         func(flowID string) framework.FlowQueueAccessor
 	IterateQueuesFunc func(callback func(queue framework.FlowQueueAccessor) (keepIterating bool))
 }
 
-func (m *MockPriorityBandAccessor) Priority() uint       { return m.PriorityV }
+func (m *MockPriorityBandAccessor) Priority() int        { return m.PriorityV }
 func (m *MockPriorityBandAccessor) PriorityName() string { return m.PriorityNameV }
 
 func (m *MockPriorityBandAccessor) FlowKeys() []types.FlowKey {
diff --git a/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs/fcfs.go b/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs/fcfs.go
index edcc02a..7addb9d 100644
--- a/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs/fcfs.go
+++ b/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs/fcfs.go
@@ -26,6 +26,32 @@ import (
 )
 
 // FCFSPolicyName is the name of the FCFS policy implementation.
+//
+// This policy implements a First-Come, First-Served (FCFS) strategy by selecting the item with the earliest logical
+// enqueue time.
+//
+// # Behavior and Queue Pairing
+//
+// The behavioral guarantees of this policy are critically dependent on the capabilities of the `framework.SafeQueue` it
+// is paired with. The system distinguishes between:
+//   - "Logical Enqueue Time": The timestamp when a request first arrives at the `controller.FlowController`.
+//   - "Physical Enqueue Time": The timestamp when a request is added to a specific shard's queue, which happens later.
+//
+// This policy's behavior changes accordingly:
+//   - Paired with a `CapabilityPriorityConfigurable` queue, it provides strict FCFS ordering based on logical enqueue
+//     time, aligning with this policy's vended `framework.ItemComparator`.
+//     This configuration ensures that requests are processed in the order they arrived at the controller, providing the
+//     most intuitive behavior.
+//   - Paired with a `CapabilityFIFO` queue, it provides approximate FCFS ordering based on physical arrival order at
+//     the `framework.SafeQueue`.
+//     This configuration offers higher performance at the cost of strict logical-time ordering, as the
+//     `controller.FlowController`'s "bounce-and-retry" mechanic for Draining shards means a bounced request may be
+//     processed after a request that logically darrived later.
+//
+// Given that true end-to-end ordering is non-deterministic in a distributd system, this policy defaults to pairing with
+// a CapabilityFIFO` queue (like "ListQueue") to prioritize performance and high throughput. For users who require the
+// strictest possible logical-time ordering that this layer can provide, explicitly pairing this policy with a
+// `CapabilityPriorityConfigurable` queue is recommended.
 const FCFSPolicyName = "FCFS"
 
 func init() {
@@ -35,7 +61,9 @@ func init() {
 		})
 }
 
-// fcfs (First-Come, First-Served) implements the `framework.IntraFlowDispatchPolicy` interface.
+// fcfs is the internal implementation of the FCFS policy.
+// See the documentation for the exported `FCFSPolicyName` constant for detailed user-facing information about its
+// behavior.
 type fcfs struct {
 	comparator framework.ItemComparator
 }
@@ -70,9 +98,10 @@ func (p *fcfs) Comparator() framework.ItemComparator {
 	return p.comparator
 }
 
-// RequiredQueueCapabilities specifies that this policy needs a queue that supports FIFO operations.
+// RequiredQueueCapabilities returns an empty slice, indicating that this policy can operate with any queue.
+// See the `FCFSPolicyName` constant's documentation for details on the behavioral trade-offs.
 func (p *fcfs) RequiredQueueCapabilities() []framework.QueueCapability {
-	return []framework.QueueCapability{framework.CapabilityFIFO}
+	return []framework.QueueCapability{}
 }
 
 // --- enqueueTimeComparator ---
diff --git a/pkg/epp/flowcontrol/framework/plugins/queue/listqueue/listqueue.go b/pkg/epp/flowcontrol/framework/plugins/queue/listqueue/listqueue.go
index 8e123b6..792e3a4 100644
--- a/pkg/epp/flowcontrol/framework/plugins/queue/listqueue/listqueue.go
+++ b/pkg/epp/flowcontrol/framework/plugins/queue/listqueue/listqueue.go
@@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package listqueue provides a simple, concurrent-safe queue implementation using a standard library
-// `container/list.List` as the underlying data structure for FIFO (First-In, First-Out) behavior.
+// Package listqueue provides a high-performance, concurrent-safe FIFO (First-In, First-Out) implementation of
+// implementation of the `framework.SafeQueue` based on the standard library's `container/list`.
 package listqueue
 
 import (
@@ -28,7 +28,28 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
 )
 
-// ListQueueName is the name of the list queue implementation.
+// ListQueueName is the name of the list-based queue implementation.
+//
+// This queue provides a high-performance, low-overhead implementation based on a standard `container/list`.
+// It advertises the `CapabilityFIFO`.
+//
+// # Behavioral Guarantees
+//
+// The core guarantee of this queue is strict physical First-In, First-Out (FIFO) ordering. It processes items in the
+// exact order they are added to the queue on a specific shard.
+//
+// # Performance and Trade-offs
+//
+// Because the physical insertion order may not match a request's logical arrival time (due to the
+// `controller.FlowController`'s internal "bounce-and-retry" mechanic), this queue provides an*approximate FCFS behavior
+// from a system-wide perspective.
+//
+// Given that true end-to-end ordering is non-deterministic in a distributed system, this high-performance queue is the
+// recommended default for most FCFS-like policies. It prioritizes throughput and efficiency, which aligns with the
+// primary goal of the Flow Control system.
+//
+// For workloads that require the strictest possible logical-time ordering this layer can provide, explicitly using a
+// queue that supports `CapabilityPriorityConfigurable` is the appropriate choice.
 const ListQueueName = "ListQueue"
 
 func init() {
@@ -39,8 +60,8 @@ func init() {
 		})
 }
 
-// listQueue implements the `framework.SafeQueue` interface using a standard `container/list.List` for FIFO behavior.
-// This implementation is concurrent-safe.
+// listQueue is the internal implementation of the ListQueue.
+// See the documentation for the exported `ListQueueName` constant for detailed user-facing information.
 type listQueue struct {
 	requests *list.List
 	byteSize atomic.Uint64
diff --git a/pkg/epp/flowcontrol/framework/policies.go b/pkg/epp/flowcontrol/framework/policies.go
index 5fc3e64..eeea034 100644
--- a/pkg/epp/flowcontrol/framework/policies.go
+++ b/pkg/epp/flowcontrol/framework/policies.go
@@ -168,7 +168,7 @@ type FlowQueueAccessor interface {
 // Conformance: Implementations MUST ensure all methods are goroutine-safe for concurrent access.
 type PriorityBandAccessor interface {
 	// Priority returns the numerical priority level of this band.
-	Priority() uint
+	Priority() int
 
 	// PriorityName returns the human-readable name of this priority band.
 	PriorityName() string
diff --git a/pkg/epp/flowcontrol/registry/config.go b/pkg/epp/flowcontrol/registry/config.go
index ed98ab8..af345a6 100644
--- a/pkg/epp/flowcontrol/registry/config.go
+++ b/pkg/epp/flowcontrol/registry/config.go
@@ -19,6 +19,7 @@ package registry
 import (
 	"errors"
 	"fmt"
+	"time"
 
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
@@ -30,99 +31,242 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/queue/listqueue"
 )
 
-// Config holds the master configuration for the entire `FlowRegistry`. It serves as the top-level blueprint, defining
-// global capacity limits and the structure of its priority bands.
+// =============================================================================
+// Default Values
+// =============================================================================
+
+const (
+	// defaultPriorityBandMaxBytes is the default global capacity for a priority band if not explicitly configured.
+	// It is set to 1 GB.
+	defaultPriorityBandMaxBytes uint64 = 1_000_000_000
+	// defaultIntraFlowDispatchPolicy is the default policy for selecting items within a single flow's queue.
+	defaultIntraFlowDispatchPolicy intra.RegisteredPolicyName = fcfs.FCFSPolicyName
+	// defaultInterFlowDispatchPolicy is the default policy for selecting which flow's queue to service next.
+	defaultInterFlowDispatchPolicy inter.RegisteredPolicyName = besthead.BestHeadPolicyName
+	// defaultQueue is the default queue implementation for flows.
+	defaultQueue queue.RegisteredQueueName = listqueue.ListQueueName
+	// defaultInitialShardCount is the default number of parallel shards to create when the registry is initialized.
+	defaultInitialShardCount int = 1
+	// defaultFlowGCTimeout is the default duration of inactivity after which an idle flow is garbage collected.
+	// This also serves as the interval for the periodic garbage collection scan.
+	defaultFlowGCTimeout time.Duration = 5 * time.Minute
+	// defaultEventChannelBufferSize is the default size of the buffered channel for control plane events.
+	defaultEventChannelBufferSize int = 4096
+)
+
+// =============================================================================
+// Global Configuration (FlowRegistry)
+// =============================================================================
+
+// Config holds the master configuration for the entire `FlowRegistry`.
+// It serves as the top-level blueprint, defining global settings and the templates for its priority bands.
 //
-// This master configuration is validated and defaulted once at startup. It is then partitioned and distributed to each
-// internal `registryShard`, ensuring a consistent and predictable state across the system.
+// This configuration is validated and defaulted once at startup. It is then used to generate partitioned `ShardConfig`
+// instances for each internal `registryShard`.
 type Config struct {
 	// MaxBytes defines an optional, global maximum total byte size limit aggregated across all priority bands and shards.
 	// The `controller.FlowController` enforces this limit in addition to per-band capacity limits.
-	//
-	// Optional: Defaults to 0, which signifies that the global limit is ignored.
+	// A value of 0 signifies that this global limit is ignored, and only per-band limits apply.
+	// Optional: Defaults to 0.
 	MaxBytes uint64
 
-	// PriorityBands defines the set of priority bands managed by the `FlowRegistry`. The configuration for each band,
-	// including its default policies and queue types, is specified here.
-	//
+	// PriorityBands defines the set of priority band templates managed by the `FlowRegistry`.
+	// The configuration for each band, including its default policies and queue types, is specified here.
+	// These templates are used to generate partitioned `ShardPriorityBandConfig`s.
 	// Required: At least one `PriorityBandConfig` must be provided for a functional registry.
 	PriorityBands []PriorityBandConfig
+
+	// InitialShardCount specifies the number of parallel shards to create when the registry is initialized.
+	// This value must be greater than zero.
+	// Optional: Defaults to `defaultInitialShardCount` (1).
+	InitialShardCount int
+
+	// FlowGCTimeout defines the interval at which the registry scans for and garbage collects idle flows. A flow is
+	// collected if it has been observed to be Idle for at least one full scan interval.
+	// Optional: Defaults to `defaultFlowGCTimeout` (5 minutes).
+	FlowGCTimeout time.Duration
+
+	// EventChannelBufferSize defines the size of the buffered channel used for internal control plane events.
+	// A larger buffer can absorb larger bursts of events (e.g., from many queues becoming non-empty simultaneously)
+	// without blocking the data path, but consumes more memory.
+	// This value must be greater than zero.
+	// Optional: Defaults to `defaultEventChannelBufferSize` (4096).
+	EventChannelBufferSize int
+
+	// priorityBandMap provides O(1) lookups of `PriorityBandConfig` by priority level.
+	// Crucially, this map serves as a correctness mechanism. It ensures that accessors return a safe, stable pointer to
+	// the correct element within this specific configuration instance, preventing common "pointer-to-loop-variable"
+	// errors, especially across deep copies or partitioning.
+	// It is populated during validation and when the config is copied or partitioned.
+	priorityBandMap map[int]*PriorityBandConfig
+
+	// Factory functions used for plugin instantiation during configuration validation.
+	// These enable dependency injection for unit testing the validation logic.
+	interFlowDispatchPolicyFactory interFlowDispatchPolicyFactory
+	intraFlowDispatchPolicyFactory intraFlowDispatchPolicyFactory
+	queueFactory                   queueFactory
 }
 
-// partition calculates and returns a new `Config` with capacity values partitioned for a specific shard.
-// This method ensures that the total capacity is distributed as evenly as possible across all shards.
-func (c *Config) partition(shardIndex, totalShards int) (*Config, error) {
-	if totalShards <= 0 || shardIndex < 0 || shardIndex >= totalShards {
-		return nil, fmt.Errorf("invalid shard partitioning arguments: shardIndex=%d, totalShards=%d",
-			shardIndex, totalShards)
-	}
+// PriorityBandConfig defines the configuration template for a single priority band.
+// It establishes the default behaviors (such as queueing and dispatch policies) and total capacity limits for all flows
+// that operate at this priority level.
+type PriorityBandConfig struct {
+	// Priority is the unique numerical priority level for this band.
+	// Convention: Highest numeric value corresponds to highest priority (centered on 0).
+	// Required.
+	Priority int
 
-	partitionValue := func(total uint64) uint64 {
-		if total == 0 {
-			return 0
-		}
-		base := total / uint64(totalShards)
-		remainder := total % uint64(totalShards)
-		if uint64(shardIndex) < remainder {
-			return base + 1
-		}
-		return base
-	}
+	// PriorityName is a human-readable name for this priority band (e.g., "Critical", "Standard").
+	// It must be unique across all priority bands in the configuration.
+	// Required.
+	PriorityName string
 
-	newCfg := &Config{
-		MaxBytes:      partitionValue(c.MaxBytes),
-		PriorityBands: make([]PriorityBandConfig, len(c.PriorityBands)),
+	// IntraFlowDispatchPolicy specifies the default name of the policy used to select a request from within a single
+	// flow's queue in this band.
+	// Optional: Defaults to `defaultIntraFlowDispatchPolicy` ("FCFS").
+	IntraFlowDispatchPolicy intra.RegisteredPolicyName
+
+	// InterFlowDispatchPolicy specifies the name of the policy used to select which flow's queue to service next from
+	// this band.
+	// Optional: Defaults to `defaultInterFlowDispatchPolicy` ("BestHead").
+	InterFlowDispatchPolicy inter.RegisteredPolicyName
+
+	// Queue specifies the default name of the `framework.SafeQueue` implementation for flow queues in this band.
+	// Optional: Defaults to `defaultQueue` ("ListQueue").
+	Queue queue.RegisteredQueueName
+
+	// MaxBytes defines the maximum total byte size for this priority band, aggregated across all shards.
+	// Optional: Defaults to `defaultPriorityBandMaxBytes` (1 GB).
+	MaxBytes uint64
+}
+
+// =============================================================================
+// Shard-Level Configuration
+// =============================================================================
+
+// ShardConfig holds the partitioned configuration for a single `registryShard`.
+// It contains only the data relevant to that shard and is derived from the global `Config`.
+type ShardConfig struct {
+	// MaxBytes is this shard's partitioned portion of the global `Config.MaxBytes` limit.
+	MaxBytes uint64
+
+	// PriorityBands holds the partitioned configuration for each priority band managed by this shard.
+	PriorityBands []ShardPriorityBandConfig
+
+	// priorityBandMap provides O(1) lookups of `ShardPriorityBandConfig` by priority level.
+	// It serves as a correctness mechanism, ensuring that accessors return a safe, stable pointer to the correct element
+	// within this specific shard configuration instance.
+	priorityBandMap map[int]*ShardPriorityBandConfig
+}
+
+// ShardPriorityBandConfig holds the partitioned configuration for a single priority band within a single shard.
+type ShardPriorityBandConfig struct {
+	// Priority is the unique numerical priority level for this band.
+	Priority int
+	// PriorityName is a unique human-readable name for this priority band.
+	PriorityName string
+	// IntraFlowDispatchPolicy is the name of the policy for dispatch within a flow's queue.
+	IntraFlowDispatchPolicy intra.RegisteredPolicyName
+	// InterFlowDispatchPolicy is the name of the policy for dispatch between flow queues.
+	InterFlowDispatchPolicy inter.RegisteredPolicyName
+	// Queue is the name of the queue implementation to use.
+	Queue queue.RegisteredQueueName
+	// MaxBytes is this shard's partitioned portion of this band's global capacity limit.
+	// The `controller.FlowController` enforces this limit for this specific shard.
+	MaxBytes uint64
+}
+
+// getBandConfig finds and returns the shard-level configuration for a specific priority level.
+// Returns an error wrapping `contracts.ErrPriorityBandNotFound` if the priority is not configured.
+func (sc *ShardConfig) getBandConfig(priority int) (*ShardPriorityBandConfig, error) {
+	if band, ok := sc.priorityBandMap[priority]; ok {
+		return band, nil
 	}
+	return nil, fmt.Errorf("shard config for priority %d not found: %w", priority, contracts.ErrPriorityBandNotFound)
+}
+
+// =============================================================================
+// Internal Methods and Helpers
+// =============================================================================
+
+// --- Validation and Defaulting ---
+
+// ValidateAndApplyDefaults checks the global configuration for validity and then creates a new `Config` object,
+// populating any empty fields with system defaults.
+// It does not mutate the receiver.
+func (c *Config) ValidateAndApplyDefaults() (*Config, error) {
+	cfg := c.deepCopy()
 
-	for i, band := range c.PriorityBands {
-		newBand := band                                  // Copy the original config
-		newBand.MaxBytes = partitionValue(band.MaxBytes) // Overwrite with the partitioned value
-		newCfg.PriorityBands[i] = newBand
+	// Apply defaults to top-level fields.
+	if cfg.InitialShardCount <= 0 {
+		cfg.InitialShardCount = defaultInitialShardCount
+	}
+	if cfg.FlowGCTimeout <= 0 {
+		cfg.FlowGCTimeout = defaultFlowGCTimeout
+	}
+	if cfg.EventChannelBufferSize <= 0 {
+		cfg.EventChannelBufferSize = defaultEventChannelBufferSize
 	}
 
-	return newCfg, nil
-}
+	// Ensure the DI factories are initialized for production use if `NewConfig` was called without options.
+	if cfg.interFlowDispatchPolicyFactory == nil {
+		cfg.interFlowDispatchPolicyFactory = inter.NewPolicyFromName
+	}
+	if cfg.intraFlowDispatchPolicyFactory == nil {
+		cfg.intraFlowDispatchPolicyFactory = intra.NewPolicyFromName
+	}
+	if cfg.queueFactory == nil {
+		cfg.queueFactory = queue.NewQueueFromName
+	}
 
-// validateAndApplyDefaults checks the configuration for validity and populates any empty fields with system defaults.
-// This method should be called once by the registry before it initializes any shards.
-func (c *Config) validateAndApplyDefaults() error {
-	if len(c.PriorityBands) == 0 {
-		return errors.New("config validation failed: at least one priority band must be defined")
+	if len(cfg.PriorityBands) == 0 {
+		return nil, errors.New("config validation failed: at least one priority band must be defined")
 	}
 
-	priorities := make(map[uint]struct{}) // Keep track of seen priorities
+	// Validate and default each priority band.
+	priorities := make(map[int]struct{})
+	priorityNames := make(map[string]struct{})
+	cfg.priorityBandMap = make(map[int]*PriorityBandConfig, len(cfg.PriorityBands))
 
-	for i := range c.PriorityBands {
-		band := &c.PriorityBands[i]
+	for i := range cfg.PriorityBands {
+		band := &cfg.PriorityBands[i]
 		if _, exists := priorities[band.Priority]; exists {
-			return fmt.Errorf("config validation failed: duplicate priority level %d found", band.Priority)
+			return nil, fmt.Errorf("config validation failed: duplicate priority level %d found", band.Priority)
 		}
 		priorities[band.Priority] = struct{}{}
 
 		if band.PriorityName == "" {
-			return errors.New("config validation failed: PriorityName is required for all priority bands")
+			return nil, fmt.Errorf("config validation failed: PriorityName is required for priority band %d", band.Priority)
 		}
+		if _, exists := priorityNames[band.PriorityName]; exists {
+			return nil, fmt.Errorf("config validation failed: duplicate priority name %q found", band.PriorityName)
+		}
+		priorityNames[band.PriorityName] = struct{}{}
+
 		if band.IntraFlowDispatchPolicy == "" {
-			band.IntraFlowDispatchPolicy = fcfs.FCFSPolicyName
+			band.IntraFlowDispatchPolicy = defaultIntraFlowDispatchPolicy
 		}
 		if band.InterFlowDispatchPolicy == "" {
-			band.InterFlowDispatchPolicy = besthead.BestHeadPolicyName
+			band.InterFlowDispatchPolicy = defaultInterFlowDispatchPolicy
 		}
 		if band.Queue == "" {
-			band.Queue = listqueue.ListQueueName
+			band.Queue = defaultQueue
+		}
+		if band.MaxBytes == 0 {
+			band.MaxBytes = defaultPriorityBandMaxBytes
 		}
 
-		// After defaulting, validate that the chosen plugins are compatible.
-		if err := validateBandCompatibility(*band); err != nil {
-			return err
+		if err := cfg.validateBandCompatibility(*band); err != nil {
+			return nil, err
 		}
+		cfg.priorityBandMap[band.Priority] = band
 	}
-	return nil
+	return cfg, nil
 }
 
-// validateBandCompatibility verifies that a band's default policy is compatible with its default queue type.
-func validateBandCompatibility(band PriorityBandConfig) error {
-	policy, err := intra.NewPolicyFromName(band.IntraFlowDispatchPolicy)
+// validateBandCompatibility verifies that a band's configured queue type has the necessary capabilities.
+func (c *Config) validateBandCompatibility(band PriorityBandConfig) error {
+	policy, err := c.intraFlowDispatchPolicyFactory(band.IntraFlowDispatchPolicy)
 	if err != nil {
 		return fmt.Errorf("failed to validate policy %q for priority band %d: %w",
 			band.IntraFlowDispatchPolicy, band.Priority, err)
@@ -130,23 +274,22 @@ func validateBandCompatibility(band PriorityBandConfig) error {
 
 	requiredCapabilities := policy.RequiredQueueCapabilities()
 	if len(requiredCapabilities) == 0 {
-		return nil // Policy has no specific requirements.
+		return nil // The policy is compatible with any queue type.
 	}
 
 	// Create a temporary queue instance to inspect its capabilities.
-	tempQueue, err := queue.NewQueueFromName(band.Queue, nil)
+	tempQueue, err := c.queueFactory(band.Queue, nil)
 	if err != nil {
-		return fmt.Errorf("failed to inspect queue type %q for priority band %d: %w", band.Queue, band.Priority, err)
+		return fmt.Errorf("failed to instantiate queue type %q for capability inspection (priority band %d): %w",
+			band.Queue, band.Priority, err)
 	}
 	queueCapabilities := tempQueue.Capabilities()
 
-	// Build a set of the queue's capabilities for efficient lookup.
 	capabilitySet := make(map[framework.QueueCapability]struct{}, len(queueCapabilities))
 	for _, cap := range queueCapabilities {
 		capabilitySet[cap] = struct{}{}
 	}
 
-	// Check if all required capabilities are present.
 	for _, req := range requiredCapabilities {
 		if _, ok := capabilitySet[req]; !ok {
 			return fmt.Errorf(
@@ -160,45 +303,165 @@ func validateBandCompatibility(band PriorityBandConfig) error {
 			)
 		}
 	}
-
 	return nil
 }
 
-// PriorityBandConfig defines the configuration for a single priority band within the `FlowRegistry`. It establishes the
-// default behaviors (such as queueing and dispatch policies) and capacity limits for all flows that operate at this
-// priority level.
-type PriorityBandConfig struct {
-	// Priority is the numerical priority level for this band.
-	// Convention: Lower numerical values indicate higher priority (e.g., 0 is highest).
-	//
-	// Required.
-	Priority uint
+// --- Partitioning Logic ---
 
-	// PriorityName is a human-readable name for this priority band (e.g., "Critical", "Standard", "Sheddable").
-	//
-	// Required.
-	PriorityName string
+// partition derives a `ShardConfig` from the master `Config` for a specific shard index.
+// It calculates the capacity distribution, ensuring that the total global capacity is distributed completely and
+// evenly.
+func (c *Config) partition(shardIndex, totalShards int) *ShardConfig {
+	shardCfg := &ShardConfig{
+		MaxBytes:        partitionUint64(c.MaxBytes, shardIndex, totalShards),
+		PriorityBands:   make([]ShardPriorityBandConfig, len(c.PriorityBands)),
+		priorityBandMap: make(map[int]*ShardPriorityBandConfig, len(c.PriorityBands)),
+	}
 
-	// IntraFlowDispatchPolicy specifies the default name of the registered policy used to select a specific request to
-	// dispatch next from within a single flow's queue in this band. This default can be overridden on a per-flow basis.
-	//
-	// Optional: If empty, a system default (e.g., "FCFS") is used.
-	IntraFlowDispatchPolicy intra.RegisteredPolicyName
+	for i, template := range c.PriorityBands {
+		shardBandCfg := ShardPriorityBandConfig{
+			Priority:                template.Priority,
+			PriorityName:            template.PriorityName,
+			IntraFlowDispatchPolicy: template.IntraFlowDispatchPolicy,
+			InterFlowDispatchPolicy: template.InterFlowDispatchPolicy,
+			Queue:                   template.Queue,
+			MaxBytes:                partitionUint64(template.MaxBytes, shardIndex, totalShards),
+		}
+		shardCfg.PriorityBands[i] = shardBandCfg
 
-	// InterFlowDispatchPolicy specifies the name of the registered policy used to select which flow's queue to service
-	// next from this band.
-	//
-	// Optional: If empty, a system default (e.g., "BestHead") is used.
-	InterFlowDispatchPolicy inter.RegisteredPolicyName
+		// Crucial: We must take the address of the element within the new slice (`shardCfg.PriorityBands`) to ensure the
+		// map pointers are correct for the newly created ShardConfig instance.
+		shardCfg.priorityBandMap[shardBandCfg.Priority] = &shardCfg.PriorityBands[i]
+	}
+	return shardCfg
+}
 
-	// Queue specifies the default name of the registered SafeQueue implementation to be used for flow queues within this
-	// band.
-	//
-	// Optional: If empty, a system default (e.g., "ListQueue") is used.
-	Queue queue.RegisteredQueueName
+// partitionUint64 distributes a total uint64 value across a number of partitions.
+// It distributes the remainder of the division one by one to the first few partitions.
+func partitionUint64(total uint64, partitionIndex, totalPartitions int) uint64 {
+	if totalPartitions <= 0 {
+		panic(fmt.Sprintf("invariant violation: cannot partition into %d partitions", totalPartitions))
+	}
+	if total == 0 {
+		return 0
+	}
+	base := total / uint64(totalPartitions)
+	remainder := total % uint64(totalPartitions)
+	// Distribute the remainder. The first `remainder` partitions get one extra from the total.
+	// For example, if total=10 and partitions=3, base=3, remainder=1. Partition 0 gets 3+1=4, partitions 1 and 2 get 3.
+	if uint64(partitionIndex) < remainder {
+		base++
+	}
+	return base
+}
 
-	// MaxBytes defines the maximum total byte size for this specific priority band, aggregated across all shards.
-	//
-	// Optional: If not set, a system default (e.g., 1 GB) is applied.
-	MaxBytes uint64
+// --- Test-Only Dependency Injection ---
+
+// configOption is a function that applies a configuration change to a `Config` object.
+// This is used exclusively for dependency injection in tests and should not be used in production code.
+type configOption func(*Config)
+
+// interFlowDispatchPolicyFactory defines the signature for a function that creates an
+// `framework.InterFlowDispatchPolicy` instance from its registered name.
+// It serves as an abstraction over the concrete `inter.NewPolicyFromName` factory, enabling dependency injection for
+// testing validation logic.
+type interFlowDispatchPolicyFactory func(name inter.RegisteredPolicyName) (framework.InterFlowDispatchPolicy, error)
+
+// intraFlowDispatchPolicyFactory defines the signature for a function that creates an
+// `framework.IntraFlowDispatchPolicy` instance from its registered name.
+// It serves as an abstraction over the concrete `intra.NewPolicyFromName` factory, enabling dependency injection for
+// testing validation logic.
+type intraFlowDispatchPolicyFactory func(name intra.RegisteredPolicyName) (framework.IntraFlowDispatchPolicy, error)
+
+// queueFactory defines the signature for a function that creates a `framework.SafeQueue` instance from its registered
+// name and a given `framework.ItemComparator`.
+// It serves as an abstraction over the concrete `queue.NewQueueFromName` factory, enabling dependency injection for
+// testing validation logic.
+type queueFactory func(
+	name queue.RegisteredQueueName,
+	comparator framework.ItemComparator,
+) (framework.SafeQueue, error)
+
+// withInterFlowDispatchPolicyFactory returns a test-only `configOption` that overrides the factory function for
+// creating `framework.InterFlowDispatchPolicy` instances.
+// This is used exclusively for testing validation logic.
+// test-only
+func withInterFlowDispatchPolicyFactory(factory interFlowDispatchPolicyFactory) configOption {
+	return func(c *Config) {
+		c.interFlowDispatchPolicyFactory = factory
+	}
+}
+
+// withIntraFlowDispatchPolicyFactory returns a test-only `configOption` that overrides the factory function for
+// creating `framework.IntraFlowDispatchPolicy` instances.
+// This is used exclusively for testing validation logic.
+// test-only
+func withIntraFlowDispatchPolicyFactory(factory intraFlowDispatchPolicyFactory) configOption {
+	return func(c *Config) {
+		c.intraFlowDispatchPolicyFactory = factory
+	}
+}
+
+// withQueueFactory returns a test-only `configOption` that overrides the factory function for creating
+// `framework.SafeQueue` instances.
+// This is used exclusively for testing validation logic.
+// test-only
+func withQueueFactory(factory queueFactory) configOption {
+	return func(c *Config) {
+		c.queueFactory = factory
+	}
+}
+
+// newConfig creates a new validated and defaulted `Config` object.
+// It applies provided test-only functional options before validation and defaulting.
+// It does not mutate the input `cfg`.
+// test-only
+func newConfig(cfg Config, opts ...configOption) (*Config, error) {
+	newCfg := cfg.deepCopy()
+	for _, opt := range opts {
+		opt(newCfg)
+	}
+	return newCfg.ValidateAndApplyDefaults()
+}
+
+// --- Internal Utilities ---
+
+// deepCopy creates a deep copy of the `Config` object.
+func (c *Config) deepCopy() *Config {
+	if c == nil {
+		return nil
+	}
+	newCfg := &Config{
+		MaxBytes:                       c.MaxBytes,
+		InitialShardCount:              c.InitialShardCount,
+		FlowGCTimeout:                  c.FlowGCTimeout,
+		EventChannelBufferSize:         c.EventChannelBufferSize,
+		PriorityBands:                  make([]PriorityBandConfig, len(c.PriorityBands)),
+		interFlowDispatchPolicyFactory: c.interFlowDispatchPolicyFactory,
+		intraFlowDispatchPolicyFactory: c.intraFlowDispatchPolicyFactory,
+		queueFactory:                   c.queueFactory,
+	}
+
+	// PriorityBandConfig contains only value types, so a slice copy is sufficient for a deep copy.
+	copy(newCfg.PriorityBands, c.PriorityBands)
+
+	if c.priorityBandMap != nil {
+		newCfg.priorityBandMap = make(map[int]*PriorityBandConfig, len(c.PriorityBands))
+		// Crucial: We must rebuild the map and take the address of the elements within the new slice (`newCfg.PriorityBands`)
+		// to ensure the map pointers are correct for the newly created `Config` instance.
+		for i := range newCfg.PriorityBands {
+			band := &newCfg.PriorityBands[i]
+			newCfg.priorityBandMap[band.Priority] = band
+		}
+	}
+	return newCfg
+}
+
+// getBandConfig finds and returns the global configuration template for a specific priority level.
+// Returns an error wrapping `contracts.ErrPriorityBandNotFound` if the priority is not configured.
+func (c *Config) getBandConfig(priority int) (*PriorityBandConfig, error) {
+	if band, ok := c.priorityBandMap[priority]; ok {
+		return band, nil
+	}
+	return nil, fmt.Errorf("global config for priority %d not found: %w", priority, contracts.ErrPriorityBandNotFound)
 }
diff --git a/pkg/epp/flowcontrol/registry/connection.go b/pkg/epp/flowcontrol/registry/connection.go
new file mode 100644
index 0000000..cb98316
--- /dev/null
+++ b/pkg/epp/flowcontrol/registry/connection.go
@@ -0,0 +1,44 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package registry
+
+import (
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
+)
+
+// connection is the concrete, un-exported implementation of the `contracts.ActiveFlowConnection` interface.
+// It is a temporary handle created for the duration of a single `WithConnection` call.
+type connection struct {
+	registry *FlowRegistry
+	key      types.FlowKey
+}
+
+var _ contracts.ActiveFlowConnection = &connection{}
+
+// Shards returns a stable snapshot of accessors for all internal state shards.
+func (c *connection) ActiveShards() []contracts.RegistryShard {
+	c.registry.mu.RLock()
+	defer c.registry.mu.RUnlock()
+
+	// Return a copy to ensure the caller cannot modify the registry's internal slice.
+	shardsCopy := make([]contracts.RegistryShard, len(c.registry.activeShards))
+	for i, s := range c.registry.activeShards {
+		shardsCopy[i] = s
+	}
+	return shardsCopy
+}
diff --git a/pkg/epp/flowcontrol/registry/doc.go b/pkg/epp/flowcontrol/registry/doc.go
index a038d3d..8ab1c5d 100644
--- a/pkg/epp/flowcontrol/registry/doc.go
+++ b/pkg/epp/flowcontrol/registry/doc.go
@@ -14,27 +14,23 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package registry provides the concrete implementation of the Flow Registry.
+// Package registry provides the concrete implementation of the `contracts.FlowRegistry` interface.
 //
-// As the stateful control plane for the entire Flow Control system, this package is responsible for managing the
-// lifecycle of all flows, queues, and policies. It serves as the "adapter" that implements the service "ports"
-// (interfaces) defined in the `contracts` package. It provides a sharded, concurrent-safe view of its state to the
-// `controller.FlowController` workers, enabling scalable, parallel request processing.
+// # Architecture: A Sharded, Concurrent Control Plane
 //
-// # Key Components
+// This package implements the flow control state machine using a sharded architecture to enable scalable, parallel
+// request processing. It separates the orchestration control plane from the request-processing data plane.
 //
-//   - `FlowRegistry`: The future top-level administrative object that will manage the entire system, including shard
-//     lifecycles and flow registration. (Not yet implemented).
+//   - `FlowRegistry`: The top-level orchestrator (Control Plane). It manages the lifecycle of all flows and shards,
+//     handling registration, garbage collection, and scaling operations.
+//   - `registryShard`: A slice of the data plane. It holds a partition of the total state and provides a
+//     read-optimized, concurrent-safe view for a single `controller.FlowController` worker.
+//   - `managedQueue`: A stateful decorator around a `framework.SafeQueue`. It is the fundamental unit of state,
+//     responsible for atomically tracking statistics (e.g., length and byte size) and ensuring data consistency.
 //
-//   - `registryShard`: A concrete implementation of the `contracts.RegistryShard` interface. It represents a single,
-//     concurrent-safe slice of the registry's state, containing a set of priority bands and the flow queues within
-//     them. This is the primary object a `controller.FlowController` worker interacts with.
+// # Concurrency Model
 //
-//   - `managedQueue`: A concrete implementation of the `contracts.ManagedQueue` interface. It acts as a stateful
-//     decorator around a `framework.SafeQueue`, adding critical registry-level functionality such as atomic statistics
-//     tracking.
-//
-//   - `Config`: The top-level configuration object that defines the structure and default behaviors of the registry,
-//     including the definition of priority bands and default policy selections. This configuration is partitioned and
-//     distributed to each `registryShard`.
+// The registry uses a multi-layered strategy to maximize performance on the hot path while ensuring correctness for
+// administrative tasks.
+// (See the `FlowRegistry` struct documentation for detailed locking rules).
 package registry
diff --git a/pkg/epp/flowcontrol/registry/managedqueue.go b/pkg/epp/flowcontrol/registry/managedqueue.go
index b52adb1..e56cdd8 100644
--- a/pkg/epp/flowcontrol/registry/managedqueue.go
+++ b/pkg/epp/flowcontrol/registry/managedqueue.go
@@ -17,6 +17,8 @@ limitations under the License.
 package registry
 
 import (
+	"fmt"
+	"sync"
 	"sync/atomic"
 
 	"github.com/go-logr/logr"
@@ -27,67 +29,90 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
 )
 
-// parentStatsReconciler defines the callback function that a `managedQueue` uses to propagate its statistics changes up
-// to its parent `registryShard`.
-type parentStatsReconciler func(lenDelta, byteSizeDelta int64)
-
-// managedQueue implements `contracts.ManagedQueue`. It is a stateful decorator that wraps a `framework.SafeQueue`,
-// augmenting it with atomic statistics tracking. This allows the parent `registryShard` to aggregate statistics across
-// many queues without locks.
+// managedQueue implements `contracts.ManagedQueue`. It acts as a stateful decorator around a `framework.SafeQueue`.
+//
+// # Role: The Stateful Statistics Decorator
+//
+// Its sole responsibility is to augment a generic queue with strictly consistent, atomic statistics tracking.
+// All mutating operations (`Add`, `Remove`, etc.) are wrapped to ensure that the queue's internal state and its
+// externally visible statistics (`Len`, `ByteSize`) are always perfectly synchronized.
+//
+// # Concurrency Model: Mutex for Writes, Atomics for Reads
 //
-// # Statistical Integrity
+// The `managedQueue` employs a hybrid locking strategy to guarantee strict consistency while maintaining high read
+// performance.
 //
-// For performance, `managedQueue` maintains its own `len` and `byteSize` fields using atomic operations. This provides
-// O(1) access for the parent `registryShard`'s aggregated statistics without needing to lock the underlying queue.
+//  1. Mutex-Protected Writes (`sync.Mutex`): A single mutex protects all mutating operations.
+//     This ensures the update to the underlying queue and the update to the internal counters occur as a single, atomic
+//     transaction.
+//  2. Synchronous Propagation: Statistics deltas are propagated synchronously within this critical section,
+//     guaranteeing a non-negativity invariant across the entire system (Shard/Registry aggregates).
+//  3. Lock-Free Reads (Atomics): The counters use `atomic.Int64`, allowing high-frequency accessors (`Len()`,
+//     `ByteSize()`) to read statistics without acquiring the mutex.
 //
-// This design is predicated on two critical assumptions:
-//  1. Exclusive Access: All mutating operations on the underlying `framework.SafeQueue` MUST be performed exclusively
-//     through this `managedQueue` wrapper. Direct access to the underlying queue will cause statistical drift.
-//  2. In-Process Queue: The `framework.SafeQueue` implementation is an in-process data structure (e.g., a list or
-//     heap). Its state MUST NOT change through external mechanisms. For example, a queue implementation backed by a
-//     distributed cache like Redis with its own TTL-based eviction policy would violate this assumption and lead to
-//     state inconsistency, as items could be removed without notifying the `managedQueue`.
+// # Invariant Protection
 //
-// This approach avoids the need for the `framework.SafeQueue` interface to return state deltas on each operation,
-// keeping its contract simpler.
+// To guarantee statistical integrity, the following invariants must be upheld:
+//  1. Exclusive Access: All mutations on the underlying `SafeQueue` MUST be performed exclusively through this wrapper.
+//  2. Non-Autonomous State: The underlying queue must not change state autonomously (e.g., no internal TTL eviction).
 type managedQueue struct {
-	// Note: There is no mutex here. Concurrency control is delegated to the underlying `framework.SafeQueue` and the
-	// atomic operations on the stats fields.
-	queue               framework.SafeQueue
-	dispatchPolicy      framework.IntraFlowDispatchPolicy
-	flowKey             types.FlowKey
-	byteSize            atomic.Uint64
-	len                 atomic.Uint64
-	reconcileShardStats parentStatsReconciler
-	logger              logr.Logger
+	// --- Immutable Identity & Dependencies (set at construction) ---
+	key            types.FlowKey
+	dispatchPolicy framework.IntraFlowDispatchPolicy
+	logger         logr.Logger
+
+	// onStatsDelta is the callback used to propagate statistics changes up to the parent shard.
+	onStatsDelta propagateStatsDeltaFunc
+	// isDraining is a callback that checks the lifecycle state of the parent shard, allowing this queue to reject new
+	// work when the shard is being decommissioned.
+	isDraining func() bool
+
+	// --- State Protected by `mu` ---
+
+	// mu protects all mutating operations. It ensures that any changes to the underlying `queue` and the updates to the
+	// atomic counters occur as a single, atomic transaction.
+	mu sync.Mutex
+	// queue is the underlying, concurrency-safe queue implementation that this `managedQueue` decorates.
+	// Its state must only be modified while holding `mu`.
+	queue framework.SafeQueue
+
+	// --- Concurrent-Safe State (Atomics) ---
+
+	// Queue-level statistics.
+	// These are written under the protection of `mu` but can be read lock-free at any time using atomic operations.
+	// They are guaranteed to be non-negative.
+	byteSize atomic.Int64
+	len      atomic.Int64
 }
 
+var _ contracts.ManagedQueue = &managedQueue{}
+
 // newManagedQueue creates a new instance of a `managedQueue`.
 func newManagedQueue(
 	queue framework.SafeQueue,
 	dispatchPolicy framework.IntraFlowDispatchPolicy,
-	flowKey types.FlowKey,
+	key types.FlowKey,
 	logger logr.Logger,
-	reconcileShardStats parentStatsReconciler,
+	onStatsDelta propagateStatsDeltaFunc,
+	isDraining func() bool,
 ) *managedQueue {
 	mqLogger := logger.WithName("managed-queue").WithValues(
-		"flowKey", flowKey,
-		"flowID", flowKey.ID,
-		"priority", flowKey.Priority,
+		"flowKey", key,
 		"queueType", queue.Name(),
 	)
 	mq := &managedQueue{
-		queue:               queue,
-		dispatchPolicy:      dispatchPolicy,
-		flowKey:             flowKey,
-		reconcileShardStats: reconcileShardStats,
-		logger:              mqLogger,
+		queue:          queue,
+		dispatchPolicy: dispatchPolicy,
+		key:            key,
+		onStatsDelta:   onStatsDelta,
+		logger:         mqLogger,
+		isDraining:     isDraining,
 	}
 	return mq
 }
 
-// FlowQueueAccessor returns a new `flowQueueAccessor` instance, which provides a read-only, policy-facing view of the
-// queue.
+// FlowQueueAccessor returns a read-only, flow-aware view of this queue.
+// This accessor is primarily used by policy plugins to inspect the queue's state in a structured way.
 func (mq *managedQueue) FlowQueueAccessor() framework.FlowQueueAccessor {
 	return &flowQueueAccessor{mq: mq}
 }
@@ -95,10 +120,19 @@ func (mq *managedQueue) FlowQueueAccessor() framework.FlowQueueAccessor {
 // Add wraps the underlying `framework.SafeQueue.Add` call and atomically updates the queue's and the parent shard's
 // statistics.
 func (mq *managedQueue) Add(item types.QueueItemAccessor) error {
+	// Enforce the system's routing contract by rejecting new work for a Draining shard.
+	// This prevents a race where a caller could route a request to a shard just as it begins to drain.
+	if mq.isDraining() {
+		return contracts.ErrShardDraining
+	}
+
+	mq.mu.Lock()
+	defer mq.mu.Unlock()
+
 	if err := mq.queue.Add(item); err != nil {
 		return err
 	}
-	mq.reconcileStats(1, int64(item.OriginalRequest().ByteSize()))
+	mq.propagateStatsDeltaLocked(1, int64(item.OriginalRequest().ByteSize()))
 	mq.logger.V(logging.TRACE).Info("Request added to queue", "requestID", item.OriginalRequest().ID())
 	return nil
 }
@@ -106,11 +140,14 @@ func (mq *managedQueue) Add(item types.QueueItemAccessor) error {
 // Remove wraps the underlying `framework.SafeQueue.Remove` call and atomically updates statistics upon successful
 // removal.
 func (mq *managedQueue) Remove(handle types.QueueItemHandle) (types.QueueItemAccessor, error) {
+	mq.mu.Lock()
+	defer mq.mu.Unlock()
+
 	removedItem, err := mq.queue.Remove(handle)
 	if err != nil {
 		return nil, err
 	}
-	mq.reconcileStats(-1, -int64(removedItem.OriginalRequest().ByteSize()))
+	mq.propagateStatsDeltaLocked(-1, -int64(removedItem.OriginalRequest().ByteSize()))
 	mq.logger.V(logging.TRACE).Info("Request removed from queue", "requestID", removedItem.OriginalRequest().ID())
 	return removedItem, nil
 }
@@ -118,110 +155,99 @@ func (mq *managedQueue) Remove(handle types.QueueItemHandle) (types.QueueItemAcc
 // Cleanup wraps the underlying `framework.SafeQueue.Cleanup` call and atomically updates statistics for all removed
 // items.
 func (mq *managedQueue) Cleanup(predicate framework.PredicateFunc) (cleanedItems []types.QueueItemAccessor, err error) {
+	mq.mu.Lock()
+	defer mq.mu.Unlock()
+
 	cleanedItems, err = mq.queue.Cleanup(predicate)
-	if err != nil || len(cleanedItems) == 0 {
-		return cleanedItems, err
+	if err != nil {
+		return nil, err
 	}
-
-	var lenDelta int64
-	var byteSizeDelta int64
-	for _, item := range cleanedItems {
-		lenDelta--
-		byteSizeDelta -= int64(item.OriginalRequest().ByteSize())
+	if len(cleanedItems) == 0 {
+		return cleanedItems, nil
 	}
-	mq.reconcileStats(lenDelta, byteSizeDelta)
-	mq.logger.V(logging.DEBUG).Info("Cleaned up queue", "removedItemCount", len(cleanedItems),
-		"lenDelta", lenDelta, "byteSizeDelta", byteSizeDelta)
+	mq.propagateStatsDeltaForRemovedItemsLocked(cleanedItems)
+	mq.logger.V(logging.DEBUG).Info("Cleaned up queue", "removedItemCount", len(cleanedItems))
 	return cleanedItems, nil
 }
 
 // Drain wraps the underlying `framework.SafeQueue.Drain` call and atomically updates statistics for all removed items.
 func (mq *managedQueue) Drain() ([]types.QueueItemAccessor, error) {
+	mq.mu.Lock()
+	defer mq.mu.Unlock()
+
 	drainedItems, err := mq.queue.Drain()
-	if err != nil || len(drainedItems) == 0 {
-		return drainedItems, err
+	if err != nil {
+		return nil, err
 	}
-
-	var lenDelta int64
-	var byteSizeDelta int64
-	for _, item := range drainedItems {
-		lenDelta--
-		byteSizeDelta -= int64(item.OriginalRequest().ByteSize())
+	if len(drainedItems) == 0 {
+		return drainedItems, nil
 	}
-	mq.reconcileStats(lenDelta, byteSizeDelta)
-	mq.logger.V(logging.DEBUG).Info("Drained queue", "itemCount", len(drainedItems),
-		"lenDelta", lenDelta, "byteSizeDelta", byteSizeDelta)
+	mq.propagateStatsDeltaForRemovedItemsLocked(drainedItems)
+	mq.logger.V(logging.DEBUG).Info("Drained queue", "itemCount", len(drainedItems))
 	return drainedItems, nil
 }
 
-// reconcileStats atomically updates the queue's own statistics and calls the parent shard's reconciler to ensure
-// aggregated stats remain consistent.
-func (mq *managedQueue) reconcileStats(lenDelta, byteSizeDelta int64) {
-	// The use of Add with a negative number on a Uint64 is the standard Go atomic way to perform subtraction, leveraging
-	// two's complement arithmetic.
-	mq.len.Add(uint64(lenDelta))
-	mq.byteSize.Add(uint64(byteSizeDelta))
-	if mq.reconcileShardStats != nil {
-		mq.reconcileShardStats(lenDelta, byteSizeDelta)
-	}
-}
-
-// --- Pass-through and accessor methods ---
+// --- Pass-through and Accessor Methods ---
 
-// Name returns the name of the underlying queue implementation.
-func (mq *managedQueue) Name() string { return mq.queue.Name() }
-
-// Capabilities returns the capabilities of the underlying queue implementation.
-func (mq *managedQueue) Capabilities() []framework.QueueCapability { return mq.queue.Capabilities() }
-
-// Len returns the number of items in the queue.
-func (mq *managedQueue) Len() int { return int(mq.len.Load()) }
-
-// ByteSize returns the total byte size of all items in the queue.
-func (mq *managedQueue) ByteSize() uint64 { return mq.byteSize.Load() }
-
-// PeekHead returns the item at the front of the queue without removing it.
+func (mq *managedQueue) Name() string                               { return mq.queue.Name() }
+func (mq *managedQueue) Capabilities() []framework.QueueCapability  { return mq.queue.Capabilities() }
+func (mq *managedQueue) Len() int                                   { return int(mq.len.Load()) }
+func (mq *managedQueue) ByteSize() uint64                           { return uint64(mq.byteSize.Load()) }
 func (mq *managedQueue) PeekHead() (types.QueueItemAccessor, error) { return mq.queue.PeekHead() }
-
-// PeekTail returns the item at the back of the queue without removing it.
 func (mq *managedQueue) PeekTail() (types.QueueItemAccessor, error) { return mq.queue.PeekTail() }
+func (mq *managedQueue) Comparator() framework.ItemComparator       { return mq.dispatchPolicy.Comparator() }
 
-// Comparator returns the `framework.ItemComparator` that defines this queue's item ordering logic, as dictated by its
-// configured dispatch policy.
-func (mq *managedQueue) Comparator() framework.ItemComparator { return mq.dispatchPolicy.Comparator() }
-
-var _ contracts.ManagedQueue = &managedQueue{}
+// --- Internal Methods ---
 
-// --- flowQueueAccessor ---
+// propagateStatsDeltaLocked updates the queue's statistics and propagates the delta to the parent shard.
+// It must be called while holding the `managedQueue.mu` lock.
+//
+// Invariant Check: This function panics if a statistic becomes negative. This enforces the non-negative invariant
+// locally, which mathematically guarantees that the aggregated statistics (Shard/Registry level) also remain
+// non-negative.
+func (mq *managedQueue) propagateStatsDeltaLocked(lenDelta, byteSizeDelta int64) {
+	newLen := mq.len.Add(lenDelta)
+	if newLen < 0 {
+		panic(fmt.Sprintf("invariant violation: managedQueue length for flow %s became negative (%d)", mq.key, newLen))
+	}
+	mq.byteSize.Add(byteSizeDelta)
 
-// flowQueueAccessor implements `framework.FlowQueueAccessor`. It provides a read-only, policy-facing view of a
-// `managedQueue`.
-type flowQueueAccessor struct {
-	mq *managedQueue
+	// Propagate the delta up to the parent shard. This propagation is lock-free and eventually consistent.
+	mq.onStatsDelta(mq.key.Priority, lenDelta, byteSizeDelta)
 }
 
-// Name returns the name of the queue.
-func (a *flowQueueAccessor) Name() string { return a.mq.Name() }
+// propagateStatsDeltaForRemovedItemsLocked calculates the total stat changes for a slice of removed items and applies
+// them. It must be called while holding the `managedQueue.mu` lock.
+func (mq *managedQueue) propagateStatsDeltaForRemovedItemsLocked(items []types.QueueItemAccessor) {
+	var lenDelta int64
+	var byteSizeDelta int64
+	for _, item := range items {
+		lenDelta--
+		byteSizeDelta -= int64(item.OriginalRequest().ByteSize())
+	}
+	mq.propagateStatsDeltaLocked(lenDelta, byteSizeDelta)
+}
 
-// Capabilities returns the capabilities of the queue.
-func (a *flowQueueAccessor) Capabilities() []framework.QueueCapability { return a.mq.Capabilities() }
+// --- `flowQueueAccessor` ---
 
-// Len returns the number of items in the queue.
-func (a *flowQueueAccessor) Len() int { return a.mq.Len() }
+// flowQueueAccessor implements `framework.FlowQueueAccessor`. It provides a read-only, policy-facing view.
+//
+// # Role: The Read-Only Proxy
+//
+// This wrapper protects system invariants. It acts as a proxy that exposes only the read-only methods.
+// This prevents policy plugins from using type assertions to access the concrete `*managedQueue` and calling mutation
+// methods, which would bypass statistics tracking.
+type flowQueueAccessor struct {
+	mq *managedQueue
+}
 
-// ByteSize returns the total byte size of all items in the queue.
-func (a *flowQueueAccessor) ByteSize() uint64 { return a.mq.ByteSize() }
+var _ framework.FlowQueueAccessor = &flowQueueAccessor{}
 
-// PeekHead returns the item at the front of the queue without removing it.
+func (a *flowQueueAccessor) Name() string                               { return a.mq.Name() }
+func (a *flowQueueAccessor) Capabilities() []framework.QueueCapability  { return a.mq.Capabilities() }
+func (a *flowQueueAccessor) Len() int                                   { return a.mq.Len() }
+func (a *flowQueueAccessor) ByteSize() uint64                           { return a.mq.ByteSize() }
 func (a *flowQueueAccessor) PeekHead() (types.QueueItemAccessor, error) { return a.mq.PeekHead() }
-
-// PeekTail returns the item at the back of the queue without removing it.
 func (a *flowQueueAccessor) PeekTail() (types.QueueItemAccessor, error) { return a.mq.PeekTail() }
-
-// Comparator returns the `framework.ItemComparator` that defines this queue's item ordering logic.
-func (a *flowQueueAccessor) Comparator() framework.ItemComparator { return a.mq.Comparator() }
-
-// FlowKey returns the `types.FlowKey` of the flow this queue accessor is associated with.
-func (a *flowQueueAccessor) FlowKey() types.FlowKey { return a.mq.flowKey }
-
-var _ framework.FlowQueueAccessor = &flowQueueAccessor{}
+func (a *flowQueueAccessor) Comparator() framework.ItemComparator       { return a.mq.Comparator() }
+func (a *flowQueueAccessor) FlowKey() types.FlowKey                     { return a.mq.key }
diff --git a/pkg/epp/flowcontrol/registry/registry.go b/pkg/epp/flowcontrol/registry/registry.go
new file mode 100644
index 0000000..3a73ef7
--- /dev/null
+++ b/pkg/epp/flowcontrol/registry/registry.go
@@ -0,0 +1,601 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package registry
+
+import (
+	"cmp"
+	"context"
+	"fmt"
+	"slices"
+	"sync"
+	"sync/atomic"
+	"time"
+
+	"github.com/go-logr/logr"
+	"k8s.io/utils/clock"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
+)
+
+// propagateStatsDeltaFunc defines the callback function used to propagate statistics changes (deltas) up the hierarchy
+// (Queue -> Shard -> Registry).
+// Implementations MUST be non-blocking (relying on atomics).
+type propagateStatsDeltaFunc func(priority int, lenDelta, byteSizeDelta int64)
+
+// bandStats holds the aggregated atomic statistics for a single priority band across all shards.
+type bandStats struct {
+	byteSize atomic.Int64
+	len      atomic.Int64
+}
+
+// flowState holds all tracking state for a single flow instance within the registry.
+type flowState struct {
+	key types.FlowKey
+
+	// gcLock protects the flow's lifecycle state.
+	// - The Garbage Collector takes an exclusive write lock to safely delete the flow.
+	// - Active connections take a shared read lock for the duration of their operation, preventing the GC from running
+	//   while allowing other connections to proceed concurrently.
+	gcLock sync.RWMutex
+
+	// leaseCount is an atomic reference counter for all concurrent, in-flight connections.
+	// It is the sole source of truth for determining if a flow is Idle.
+	leaseCount atomic.Int64
+
+	// becameIdleAt tracks the time at which the lease count last dropped to zero.
+	// A zero value indicates the flow is currently Active.
+	// This field is always protected by the gcLock's exclusive write lock during modifications.
+	becameIdleAt time.Time
+}
+
+// FlowRegistry is the concrete implementation of the `contracts.FlowRegistry` interface.
+//
+// # Role: The Central Orchestrator
+//
+// The `FlowRegistry` is the single source of truth for flow control configuration and the lifecycle manager for all
+// shards and flow instances. It provides a highly concurrent data path for request processing while ensuring
+// correctness for administrative tasks like scaling and garbage collection.
+//
+// # Concurrency Model: A Multi-Layered Strategy
+//
+// The registry is designed for high throughput by separating the concurrency domains of the request hot path, garbage
+// collection, and administrative tasks.
+//
+//  1. `sync.Map` for `flowStates` (Hot Path): The `WithConnection` method uses a `sync.Map` for highly concurrent,
+//     often lock-free, lookups and Just-In-Time registration of different flows.
+//  2. `flowState.gcLock` (`sync.RWMutex`) for Per-Flow Lifecycle: Each flow has its own `RWMutex` to arbitrate between
+//     active connections and the garbage collector. This surgical locking prevents GC on one flow from impacting any
+//     other. The interaction is as follows:
+//  3. `mu (sync.RWMutex)` for Global Topology: A single registry-wide mutex protects the overall shard topology during
+//     infrequent administrative operations like scaling.
+//
+// # Flow Lifecycle: Lease-Based with Surgical GC
+//
+// A flow's lifecycle is managed by a lease-based reference count.
+//
+//  1. Lease Acquisition: A client calls `WithConnection` to begin a managed session. This acquires a lease by
+//     incrementing an atomic counter.
+//  2. Lease Release: Lease release is automatic and guaranteed. When the callback function provided to `WithConnection`
+//     returns, the lease is released by decrementing the atomic counter. When the count reaches zero, the flow is
+//     marked Idle with a timestamp.
+//  3. Garbage Collection: A background task scans for Idle flows. To prevent a TOCTOU race, the GC acquires an
+//     exclusive lock on the specific `flowState.gcLock` before re-verifying the lease count is still zero and
+//     proceeding with deletion.
+//
+// # Locking Order
+//
+// To prevent deadlocks, locks MUST be acquired in the following order:
+//
+//  1. `FlowRegistry.mu` (Registry-level write lock)
+//  2. `registryShard.mu` (Shard-level write lock)
+//  3. `flowState.gcLock` (Per-flow GC lock)
+type FlowRegistry struct {
+	// --- Immutable dependencies (set at construction) ---
+	config *Config
+	logger logr.Logger
+	clock  clock.WithTicker
+
+	// --- Lock-free / Concurrent state (hot path) ---
+
+	// flowStates tracks all flow instances, keyed by `types.FlowKey`.
+	flowStates sync.Map // stores `types.FlowKey` -> *flowState
+
+	// Globally aggregated statistics, updated atomically via lock-free propagation.
+	totalByteSize        atomic.Int64
+	totalLen             atomic.Int64
+	perPriorityBandStats map[int]*bandStats // Keyed by priority.
+
+	// --- Administrative state (protected by `mu`) ---
+
+	mu             sync.RWMutex
+	activeShards   []*registryShard
+	drainingShards map[string]*registryShard
+	allShards      []*registryShard // Cached, sorted combination of Active and Draining shards
+	nextShardID    uint64
+}
+
+var _ contracts.FlowRegistry = &FlowRegistry{}
+
+// RegistryOption allows configuring the `FlowRegistry` during initialization.
+type RegistryOption func(*FlowRegistry)
+
+// withClock sets the clock abstraction for deterministic testing.
+// test-only
+func withClock(clk clock.WithTickerAndDelayedExecution) RegistryOption {
+	return func(fr *FlowRegistry) {
+		if clk != nil {
+			fr.clock = clk
+		}
+	}
+}
+
+// NewFlowRegistry creates and initializes a new `FlowRegistry` instance.
+func NewFlowRegistry(config Config, logger logr.Logger, opts ...RegistryOption) (*FlowRegistry, error) {
+	cfg := config.deepCopy()
+	fr := &FlowRegistry{
+		config:               cfg,
+		logger:               logger.WithName("flow-registry"),
+		activeShards:         []*registryShard{},
+		drainingShards:       make(map[string]*registryShard),
+		perPriorityBandStats: make(map[int]*bandStats, len(cfg.PriorityBands)),
+	}
+
+	for _, opt := range opts {
+		opt(fr)
+	}
+	if fr.clock == nil {
+		fr.clock = &clock.RealClock{}
+	}
+
+	for i := range config.PriorityBands {
+		band := &config.PriorityBands[i]
+		fr.perPriorityBandStats[band.Priority] = &bandStats{}
+	}
+
+	if err := fr.updateShardCount(cfg.InitialShardCount); err != nil {
+		return nil, fmt.Errorf("failed to initialize shards: %w", err)
+	}
+	fr.logger.V(logging.DEFAULT).Info("FlowRegistry initialized successfully")
+	return fr, nil
+}
+
+// Run starts the registry's background garbage collection loop.
+// It blocks until the provided context is cancelled.
+func (fr *FlowRegistry) Run(ctx context.Context) {
+	fr.logger.Info("Starting FlowRegistry background garbage collection loop")
+	defer fr.logger.Info("FlowRegistry background garbage collection loop stopped")
+	gcTicker := fr.clock.NewTicker(fr.config.FlowGCTimeout)
+	defer gcTicker.Stop()
+
+	for {
+		select {
+		case <-ctx.Done():
+			return
+		case <-gcTicker.C():
+			fr.executeGCCycle()
+		}
+	}
+}
+
+// --- `contracts.FlowRegistryDataPlane` Implementation ---
+
+// Connect establishes a session for a given flow, acquiring a lifecycle lease.
+// This is the primary entry point for the data path.
+// If the flow does not exist, it is registered Just-In-Time (JIT).
+func (fr *FlowRegistry) WithConnection(key types.FlowKey, fn func(conn contracts.ActiveFlowConnection) error) error {
+	if key.ID == "" {
+		return contracts.ErrFlowIDEmpty
+	}
+
+	// --- JIT Registration ---
+	val, ok := fr.flowStates.Load(key)
+	if !ok {
+		newFlowState, err := fr.prepareNewFlow(key)
+		if err != nil {
+			return fmt.Errorf("failed to prepare JIT registration for flow %s: %w", key, err)
+		}
+
+		actual, loaded := fr.flowStates.LoadOrStore(key, newFlowState)
+		val = actual
+		if loaded {
+			// Another goroutine won the race. Use its state and discard ours.
+			// If future changes make the `managedQueue` or its components more stateful (e.g., by adding background
+			// goroutines, registering with a metrics system, or using `sync.Pool`), a deterministic cleanup function MUST be
+			// called here to release those resources promptly and prevent leaks.
+			fr.logger.V(logging.DEBUG).Info("Concurrent JIT registration detected for flow",
+				"flowKey", key, "flowID", key.ID, "priority", key.Priority)
+		}
+	}
+
+	// --- Lease Acquisition & Guaranteed Release ---
+	state := val.(*flowState)
+	state.gcLock.Lock()
+	state.leaseCount.Add(1)
+	state.becameIdleAt = time.Time{} // Mark the flow as Active.
+	state.gcLock.Unlock()
+	defer func() {
+		if state.leaseCount.Add(-1) == 0 {
+			// This was the last active lease; mark the flow as Idle.
+			state.gcLock.Lock()
+			state.becameIdleAt = fr.clock.Now()
+			state.gcLock.Unlock()
+		}
+	}()
+
+	// --- Callback Execution ---
+	// We acquire a read lock. This has two effects:
+	// 1. It allows many connections to execute this section concurrently.
+	// 2. It prevents the GC from acquiring a write lock, thus guaranteeing the flow state cannot be deleted while `fn()`
+	//    is running.
+	state.gcLock.RLock()
+	defer state.gcLock.RUnlock()
+	return fn(&connection{registry: fr, key: key})
+}
+
+// prepareNewFlow creates a new `flowState` and synchronizes its queues and policies onto all existing shards.
+func (fr *FlowRegistry) prepareNewFlow(key types.FlowKey) (*flowState, error) {
+	// Get a stable snapshot of the shard topology.
+	// An RLock is sufficient because while the list of shards must be stable, the internal state of each shard is
+	// protected by its own lock.
+	fr.mu.RLock()
+	defer fr.mu.RUnlock()
+
+	components, err := fr.buildFlowComponents(key, len(fr.allShards))
+	if err != nil {
+		return nil, err
+	}
+
+	for i, shard := range fr.allShards {
+		shard.synchronizeFlow(types.FlowSpecification{Key: key}, components[i].policy, components[i].queue)
+	}
+
+	fr.logger.Info("Successfully prepared and synchronized new flow instance",
+		"flowKey", key, "flowID", key.ID, "priority", key.Priority)
+	return &flowState{key: key}, nil
+}
+
+// --- `contracts.FlowRegistryObserver` Implementation ---
+
+// Stats returns globally aggregated statistics for the entire `FlowRegistry`.
+//
+// Statistics are aggregated using high-performance, lock-free atomic updates.
+// The returned stats represent a near-consistent snapshot of the system's state.
+// It is not perfectly atomic because the various counters are loaded independently without a global lock.
+func (fr *FlowRegistry) Stats() contracts.AggregateStats {
+	// Casts from `int64` to `uint64` are safe because the non-negativity invariant is strictly enforced at the
+	// `managedQueue` level.
+	stats := contracts.AggregateStats{
+		TotalCapacityBytes:   fr.config.MaxBytes,
+		TotalByteSize:        uint64(fr.totalByteSize.Load()),
+		TotalLen:             uint64(fr.totalLen.Load()),
+		PerPriorityBandStats: make(map[int]contracts.PriorityBandStats, len(fr.config.PriorityBands)),
+	}
+
+	for p, s := range fr.perPriorityBandStats {
+		bandCfg, err := fr.config.getBandConfig(p)
+		if err != nil {
+			panic(fmt.Sprintf("invariant violation: priority band config (%d) missing during stats aggregation: %v", p, err))
+		}
+		stats.PerPriorityBandStats[p] = contracts.PriorityBandStats{
+			Priority:      p,
+			PriorityName:  bandCfg.PriorityName,
+			CapacityBytes: bandCfg.MaxBytes,
+			ByteSize:      uint64(s.byteSize.Load()),
+			Len:           uint64(s.len.Load()),
+		}
+	}
+	return stats
+}
+
+// ShardStats returns a slice of statistics, one for each internal shard.
+func (fr *FlowRegistry) ShardStats() []contracts.ShardStats {
+	fr.mu.RLock()
+	allShards := fr.allShards
+	fr.mu.RUnlock()
+
+	shardStats := make([]contracts.ShardStats, len(allShards))
+	for i, s := range allShards {
+		shardStats[i] = s.Stats()
+	}
+	return shardStats
+}
+
+// --- Garbage Collection ---
+
+// executeGCCycle orchestrates the periodic GC of Idle flows and Drained shards.
+func (fr *FlowRegistry) executeGCCycle() {
+	fr.logger.V(logging.DEBUG).Info("Starting periodic GC scan")
+	var flowCandidates []types.FlowKey
+	fr.flowStates.Range(func(key, value interface{}) bool {
+		state := value.(*flowState)
+		state.gcLock.RLock()
+		// A flow is a candidate if its lease count is zero and its idleness timeout has expired.
+		if state.leaseCount.Load() == 0 && !state.becameIdleAt.IsZero() {
+			if fr.clock.Since(state.becameIdleAt) > fr.config.FlowGCTimeout {
+				flowCandidates = append(flowCandidates, key.(types.FlowKey))
+			}
+		}
+		state.gcLock.RUnlock()
+		return true
+	})
+	if len(flowCandidates) > 0 {
+		fr.verifyAndSweepFlows(flowCandidates)
+	}
+	fr.sweepDrainingShards()
+}
+
+// verifyAndSweepFlows performs the "verify" and "sweep" phases of GC for Idle flows.
+// For each candidate, it acquires an exclusive lock on that specific flow's state, re-verifies it is still Idle, and
+// then safely performs the deletion.
+func (fr *FlowRegistry) verifyAndSweepFlows(candidates []types.FlowKey) {
+	fr.logger.V(logging.DEBUG).Info("Starting GC Verify and Sweep phase for flows", "candidateCount", len(candidates))
+
+	// Get a stable snapshot of the shard topology, so the list of shards does not change while we are preparing to delete
+	// queues from them.
+	fr.mu.RLock()
+	shardsSnapshot := fr.allShards
+	fr.mu.RUnlock()
+
+	var collectedCount int
+	for _, key := range candidates {
+		val, ok := fr.flowStates.Load(key)
+		if !ok {
+			// Benign race: the flow was already deleted by a previous GC cycle or another process. We can safely ignore it.
+			continue
+		}
+		state := val.(*flowState)
+
+		// Acquire the exclusive write lock for this specific flow, blocking any new `Connect/Close` operations for this
+		// flow only and ensuring the state is stable for our check. All other flows are unaffected.
+		state.gcLock.Lock()
+
+		// Verify Phase:
+		if state.leaseCount.Load() > 0 {
+			// Verification failed. A new lease was acquired between our initial scan and acquiring the lock.
+			// The flow is Active again, so we leave it alone.
+			fr.logger.V(logging.DEBUG).Info("GC of flow aborted: re-verification failed (flow is Active)",
+				"flowKey", key, "flowID", key.ID, "priority", key.Priority,
+				"leaseCount", state.leaseCount.Load(), "becameIdleAt", state.becameIdleAt)
+			state.gcLock.Unlock()
+			continue
+		}
+
+		// Sweep Phase:
+		for _, shard := range shardsSnapshot {
+			shard.deleteFlow(key)
+		}
+		fr.flowStates.Delete(key)
+		fr.logger.V(logging.VERBOSE).Info("Successfully verified and swept flow",
+			"flowKey", key, "flowID", key.ID, "priority", key.Priority, "becameIdleAt", state.becameIdleAt)
+		collectedCount++
+		state.gcLock.Unlock()
+	}
+
+	fr.logger.V(logging.DEBUG).Info("GC Verify and Sweep phase completed", "flowsCollected", collectedCount)
+}
+
+// sweepDrainingShards finalizes the removal of drained shards.
+func (fr *FlowRegistry) sweepDrainingShards() {
+	// Acquire a full write lock on the registry as we may be modifying the shard topology.
+	fr.mu.Lock()
+	defer fr.mu.Unlock()
+
+	var shardsToDelete []string
+	for id, shard := range fr.drainingShards {
+		// A Draining shard is ready for GC once it is completely empty.
+		// Draining shards do not accept new work (enforced at `managedQueue.Add`), so `shard.totalLen.Load()` can only
+		// monotonically decrease.
+		if shard.totalLen.Load() == 0 {
+			shardsToDelete = append(shardsToDelete, id)
+		}
+	}
+
+	if len(shardsToDelete) > 0 {
+		fr.logger.V(logging.DEBUG).Info("Garbage collecting drained shards", "shardIDs", shardsToDelete)
+		for _, id := range shardsToDelete {
+			delete(fr.drainingShards, id)
+		}
+		fr.updateAllShardsCacheLocked()
+	}
+}
+
+// --- Shard Management (Scaling) ---
+
+// updateShardCount dynamically adjusts the number of internal state shards.
+func (fr *FlowRegistry) updateShardCount(n int) error {
+	if n <= 0 {
+		return fmt.Errorf("%w: shard count must be a positive integer, but got %d", contracts.ErrInvalidShardCount, n)
+	}
+
+	// Use a full write lock as this is a major structural change to the shard topology.
+	fr.mu.Lock()
+	defer fr.mu.Unlock()
+
+	currentActiveShards := len(fr.activeShards)
+	if n == currentActiveShards {
+		return nil
+	}
+
+	if n > currentActiveShards {
+		return fr.executeScaleUpLocked(n)
+	}
+	fr.executeScaleDownLocked(n)
+	return nil
+}
+
+// executeScaleUpLocked handles adding new shards.
+// It uses a "prepare-then-commit" pattern to ensure that the entire scale-up operation is transactional and never
+// leaves the system in a partially-synchronized, inconsistent state.
+//
+// The preparation phase iterates over all existing flows once, pre-building all necessary components for every new
+// shard. This requires O(M*K) operations (M=flows, K=new shards) and is performed while holding the main control plane
+// lock. If M is large, this operation may block the control plane for a significant duration.
+//
+// Expects the registry's write lock to be held.
+func (fr *FlowRegistry) executeScaleUpLocked(newTotalActive int) error {
+	currentActive := len(fr.activeShards)
+	numToAdd := newTotalActive - currentActive
+	fr.logger.Info("Scaling up shards", "currentActive", currentActive, "newTotalActive", newTotalActive)
+
+	// Prepare All New Shard Objects (Fallible):
+	newShards := make([]*registryShard, numToAdd)
+	for i := range numToAdd {
+		// Using a padding of 4 allows for up to 9999 shards, which is a very safe upper bound.
+		shardID := fmt.Sprintf("shard-%04d", fr.nextShardID+uint64(i))
+		partitionedConfig := fr.config.partition(currentActive+i, newTotalActive)
+		shard, err := newShard(
+			shardID,
+			partitionedConfig,
+			fr.logger,
+			fr.propagateStatsDelta,
+			fr.config.interFlowDispatchPolicyFactory,
+		)
+		if err != nil {
+			return fmt.Errorf("failed to create new shard object %s: %w", shardID, err)
+		}
+		newShards[i] = shard
+	}
+
+	// Prepare All Components for All New Shards (Fallible):
+	// Pre-build every component for every existing flow on every new shard.
+	// If any single component fails to build, the entire scale-up operation is aborted, and all prepared data is
+	// discarded, leaving the system state clean.
+	allComponents := make(map[types.FlowKey][]flowComponents)
+	var rangeErr error
+	fr.flowStates.Range(func(key, _ interface{}) bool {
+		flowKey := key.(types.FlowKey)
+		components, err := fr.buildFlowComponents(flowKey, len(newShards))
+		if err != nil {
+			rangeErr = fmt.Errorf("failed to prepare components for flow %s on new shards: %w", flowKey, err)
+			return false
+		}
+		allComponents[flowKey] = components
+		return true
+	})
+	if rangeErr != nil {
+		return rangeErr
+	}
+
+	// Commit (Infallible):
+	for i, shard := range newShards {
+		for key, components := range allComponents {
+			shard.synchronizeFlow(types.FlowSpecification{Key: key}, components[i].policy, components[i].queue)
+		}
+	}
+	fr.activeShards = append(fr.activeShards, newShards...)
+	fr.nextShardID += uint64(numToAdd)
+	fr.repartitionShardConfigsLocked()
+	fr.updateAllShardsCacheLocked()
+	return nil
+}
+
+// executeScaleDownLocked handles marking shards for graceful draining.
+// Expects the registry's write lock to be held.
+func (fr *FlowRegistry) executeScaleDownLocked(newTotalActive int) {
+	currentActive := len(fr.activeShards)
+	fr.logger.Info("Scaling down shards", "currentActive", currentActive, "newTotalActive", newTotalActive)
+
+	shardsToDrain := fr.activeShards[newTotalActive:]
+	fr.activeShards = fr.activeShards[:newTotalActive]
+	for _, shard := range shardsToDrain {
+		fr.drainingShards[shard.id] = shard
+		shard.markAsDraining()
+	}
+
+	fr.repartitionShardConfigsLocked()
+	fr.updateAllShardsCacheLocked()
+}
+
+// repartitionShardConfigsLocked updates the configuration for all active shards.
+// Expects the registry's write lock to be held.
+func (fr *FlowRegistry) repartitionShardConfigsLocked() {
+	numActive := len(fr.activeShards)
+	for i, shard := range fr.activeShards {
+		newPartitionedConfig := fr.config.partition(i, numActive)
+		shard.updateConfig(newPartitionedConfig)
+	}
+}
+
+// --- Internal Helpers ---
+
+// flowComponents holds the plugin instances created for a single flow on a single shard.
+type flowComponents struct {
+	policy framework.IntraFlowDispatchPolicy
+	queue  framework.SafeQueue
+}
+
+// buildFlowComponents instantiates the necessary plugin components for a new flow instance.
+// It creates a distinct instance of each component for each shard to ensure state isolation.
+func (fr *FlowRegistry) buildFlowComponents(key types.FlowKey, numInstances int) ([]flowComponents, error) {
+	bandConfig, err := fr.config.getBandConfig(key.Priority)
+	if err != nil {
+		return nil, err
+	}
+
+	allComponents := make([]flowComponents, numInstances)
+	for i := range numInstances {
+		policy, err := fr.config.intraFlowDispatchPolicyFactory(bandConfig.IntraFlowDispatchPolicy)
+		if err != nil {
+			return nil, fmt.Errorf("failed to instantiate intra-flow policy %q for flow %s: %w",
+				bandConfig.IntraFlowDispatchPolicy, key, err)
+		}
+		q, err := fr.config.queueFactory(bandConfig.Queue, policy.Comparator())
+		if err != nil {
+			return nil, fmt.Errorf("failed to instantiate queue %q for flow %s: %w",
+				bandConfig.Queue, key, err)
+		}
+		allComponents[i] = flowComponents{policy: policy, queue: q}
+	}
+	return allComponents, nil
+}
+
+// updateAllShardsCacheLocked recalculates the cached `allShards` slice.
+// It ensures the slice is sorted by shard ID to maintain a deterministic order.
+// Expects the registry's write lock to be held.
+func (fr *FlowRegistry) updateAllShardsCacheLocked() {
+	allShards := make([]*registryShard, 0, len(fr.activeShards)+len(fr.drainingShards))
+	allShards = append(allShards, fr.activeShards...)
+	for _, shard := range fr.drainingShards {
+		allShards = append(allShards, shard)
+	}
+
+	// Sort the combined slice by shard ID.
+	// This provides a stable, deterministic order for all consumers of the shard list, which is critical because map
+	// iteration for `drainingShards` is non-deterministic.
+	// While this is a lexicographical sort, our shard ID format is padded with leading zeros (e.g., "shard-0001"),
+	// ensuring that the string sort produces the same result as a natural numerical sort.
+	slices.SortFunc(allShards, func(a, b *registryShard) int {
+		return cmp.Compare(a.id, b.id)
+	})
+	fr.allShards = allShards
+}
+
+// propagateStatsDelta is the top-level, lock-free aggregator for all statistics.
+func (fr *FlowRegistry) propagateStatsDelta(priority int, lenDelta, byteSizeDelta int64) {
+	stats, ok := fr.perPriorityBandStats[priority]
+	if !ok {
+		panic(fmt.Sprintf("invariant violation: priority band (%d) stats missing during propagation", priority))
+	}
+
+	stats.len.Add(lenDelta)
+	stats.byteSize.Add(byteSizeDelta)
+	fr.totalLen.Add(lenDelta)
+	fr.totalByteSize.Add(byteSizeDelta)
+}
diff --git a/pkg/epp/flowcontrol/registry/shard.go b/pkg/epp/flowcontrol/registry/shard.go
index eb11dc7..4a7918e 100644
--- a/pkg/epp/flowcontrol/registry/shard.go
+++ b/pkg/epp/flowcontrol/registry/shard.go
@@ -18,7 +18,7 @@ package registry
 
 import (
 	"fmt"
-	"slices"
+	"sort"
 	"sync"
 	"sync/atomic"
 
@@ -26,149 +26,131 @@ import (
 
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
-	inter "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/interflow/dispatch"
-	intra "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
 )
 
-// registryShard implements the `contracts.RegistryShard` interface. It represents a single, concurrent-safe slice of
-// the `FlowRegistry`'s state, providing an operational view for a single `controller.FlowController` worker.
+// priorityBand holds all `managedQueues` and configuration for a single priority level within a shard.
+type priorityBand struct {
+	// --- Immutable (set at construction) ---
+	config                  ShardPriorityBandConfig
+	interFlowDispatchPolicy framework.InterFlowDispatchPolicy
+
+	// --- State Protected by the parent shard's `mu` ---
+
+	// queues holds all `managedQueue` instances within this band, keyed by their logical `ID` string.
+	// The priority is implicit from the parent `priorityBand`.
+	queues map[string]*managedQueue
+
+	// --- Concurrent-Safe State (Atomics) ---
+
+	// Band-level statistics, updated via lock-free propagation from child queues.
+	byteSize atomic.Int64
+	len      atomic.Int64
+}
+
+// registryShard implements the `contracts.RegistryShard` interface.
+//
+// # Role: The Data Plane Slice
 //
-// # Responsibilities
+// It represents a single, concurrent-safe slice of the registry's total state, acting as an independent, parallel
+// execution unit. It provides a read-optimized view for a `controller.FlowController` worker, partitioning the overall
+// system state to enable horizontal scalability.
 //
-//   - Holding the partitioned configuration and state (queues, policies) for its assigned shard.
-//   - Providing read-only access to its state for the `controller.FlowController`'s dispatch loop.
-//   - Aggregating statistics from its `managedQueue` instances.
+// # Concurrency Model: `RWMutex` for Topology, Atomics for Stats
 //
-// # Concurrency
+// The `registryShard` balances read performance with write safety using a hybrid model:
 //
-// The `registryShard` uses a combination of an `RWMutex` and atomic operations to manage concurrency.
-//   - The `mu` RWMutex protects the shard's internal maps (`priorityBands`) during administrative
-//     operations like flow registration or updates. This ensures that the set of queues appears
-//     atomic to a `controller.FlowController` worker. All read-oriented methods on the shard take a read lock.
-//   - All statistics (`totalByteSize`, `totalLen`, etc.) are implemented as `atomic.Uint64` to allow for lock-free,
-//     high-performance updates from many concurrent queue operations.
+//   - `mu (sync.RWMutex)`: Protects the shard's internal topology (the maps of priority bands and queues) during
+//     administrative operations like flow registration, garbage collection, and configuration updates.
+//     Read locks are used on the hot path to look up queues, while write locks are used for infrequent structural
+//     changes.
+//   - Atomics: Aggregated statistics (`totalByteSize`, `totalLen`, etc.) and the `isDraining` flag use atomic
+//     operations, allowing for high-frequency, lock-free updates and reads of the shard's status and load, which is
+//     critical for the performance of the data path and statistics propagation.
 type registryShard struct {
-	id           string
-	logger       logr.Logger
-	config       *Config // Holds the *partitioned* config for this shard.
-	isActive     bool
-	reconcileFun parentStatsReconciler
+	// --- Immutable Identity & Dependencies (set at construction) ---
+	id     string
+	logger logr.Logger
 
-	// mu protects the shard's internal maps (`priorityBands`).
-	mu sync.RWMutex
+	// onStatsDelta is the callback used to propagate statistics changes up to the parent registry.
+	onStatsDelta propagateStatsDeltaFunc
+	// orderedPriorityLevels is a cached, sorted list of priority levels.
+	orderedPriorityLevels []int
 
-	// priorityBands is the primary lookup table for all managed queues on this shard, organized by `priority`.
-	priorityBands map[uint]*priorityBand
+	// --- State Protected by `mu` ---
 
-	// orderedPriorityLevels is a cached, sorted list of `priority` levels.
-	// It is populated at initialization to avoid repeated map key iteration and sorting during the dispatch loop,
-	// ensuring a deterministic, ordered traversal from highest to lowest priority.
-	orderedPriorityLevels []uint
-
-	// Shard-level statistics, which are updated atomically to ensure they are safe for concurrent access without locks.
-	totalByteSize atomic.Uint64
-	totalLen      atomic.Uint64
-}
-
-// priorityBand holds all the `managedQueues` and configuration for a single priority level within a shard.
-type priorityBand struct {
-	// config holds the partitioned config for this specific band.
-	config PriorityBandConfig
-
-	// queues holds all `managedQueue` instances within this band, keyed by their composite `FlowKey`.
-	queues map[types.FlowKey]*managedQueue
+	// mu protects the shard's internal topology (`priorityBands`) and `config`.
+	// TODO: This is a priority inversion issue. Administrative operations (e.g., GC) for a low-priority flow block all
+	// data path operations for high priority flows on this shard. We should replace `s.mu` with granular per-band locks.
+	// This is safe since the priority band map structure is immutable at initialization.
+	mu sync.RWMutex
+	// config holds the partitioned configuration for this shard, derived from the `FlowRegistry`'s global `Config`.
+	config *ShardConfig
+	// priorityBands is the primary lookup table for all managed queues on this shard.
+	priorityBands map[int]*priorityBand
 
-	// flowKeys is a cached slice of the keys from the `queues` map. This is an optimization to avoid repeated map key
-	// iteration in the `FlowKeys()` accessor method, making it an O(1) operation.
-	flowKeys []types.FlowKey
+	// --- Concurrent-Safe State (Atomics) ---
 
-	// Band-level statistics, which are updated atomically.
-	byteSize atomic.Uint64
-	len      atomic.Uint64
+	// isDraining indicates if the shard is gracefully shutting down.
+	isDraining atomic.Bool
 
-	// Cached policy instances for this band, created at initialization.
-	interFlowDispatchPolicy        framework.InterFlowDispatchPolicy
-	defaultIntraFlowDispatchPolicy framework.IntraFlowDispatchPolicy
+	// Shard-level statistics, updated via lock-free propagation from child queues.
+	totalByteSize atomic.Int64
+	totalLen      atomic.Int64
 }
 
+var _ contracts.RegistryShard = &registryShard{}
+
 // newShard creates a new `registryShard` instance from a partitioned configuration.
 func newShard(
 	id string,
-	partitionedConfig *Config,
+	config *ShardConfig,
 	logger logr.Logger,
-	reconcileFunc parentStatsReconciler,
+	onStatsDelta propagateStatsDeltaFunc,
+	interFlowFactory interFlowDispatchPolicyFactory,
 ) (*registryShard, error) {
 	shardLogger := logger.WithName("registry-shard").WithValues("shardID", id)
 	s := &registryShard{
 		id:            id,
 		logger:        shardLogger,
-		config:        partitionedConfig,
-		isActive:      true,
-		reconcileFun:  reconcileFunc,
-		priorityBands: make(map[uint]*priorityBand, len(partitionedConfig.PriorityBands)),
+		config:        config,
+		onStatsDelta:  onStatsDelta,
+		priorityBands: make(map[int]*priorityBand, len(config.PriorityBands)),
 	}
 
-	for _, bandConfig := range partitionedConfig.PriorityBands {
-		interPolicy, err := inter.NewPolicyFromName(bandConfig.InterFlowDispatchPolicy)
+	for _, bandConfig := range config.PriorityBands {
+		interPolicy, err := interFlowFactory(bandConfig.InterFlowDispatchPolicy)
 		if err != nil {
 			return nil, fmt.Errorf("failed to create inter-flow policy %q for priority band %d: %w",
 				bandConfig.InterFlowDispatchPolicy, bandConfig.Priority, err)
 		}
 
-		intraPolicy, err := intra.NewPolicyFromName(bandConfig.IntraFlowDispatchPolicy)
-		if err != nil {
-			return nil, fmt.Errorf("failed to create intra-flow policy %q for priority band %d: %w",
-				bandConfig.IntraFlowDispatchPolicy, bandConfig.Priority, err)
-		}
-
 		s.priorityBands[bandConfig.Priority] = &priorityBand{
-			config:                         bandConfig,
-			queues:                         make(map[types.FlowKey]*managedQueue),
-			interFlowDispatchPolicy:        interPolicy,
-			defaultIntraFlowDispatchPolicy: intraPolicy,
+			config:                  bandConfig,
+			queues:                  make(map[string]*managedQueue),
+			interFlowDispatchPolicy: interPolicy,
 		}
 		s.orderedPriorityLevels = append(s.orderedPriorityLevels, bandConfig.Priority)
 	}
-
-	// Sort the priority levels to ensure deterministic iteration order.
-	slices.Sort(s.orderedPriorityLevels)
+	sort.Slice(s.orderedPriorityLevels, func(i, j int) bool {
+		return s.orderedPriorityLevels[i] > s.orderedPriorityLevels[j]
+	})
 	s.logger.V(logging.DEFAULT).Info("Registry shard initialized successfully",
 		"priorityBandCount", len(s.priorityBands), "orderedPriorities", s.orderedPriorityLevels)
 	return s, nil
 }
 
-// reconcileStats is the single point of entry for all statistics changes within the shard. It updates the relevant
-// band's stats, the shard's total stats, and propagates the delta to the parent registry.
-func (s *registryShard) reconcileStats(priority uint, lenDelta, byteSizeDelta int64) {
-	s.totalLen.Add(uint64(lenDelta))
-	s.totalByteSize.Add(uint64(byteSizeDelta))
-
-	if band, ok := s.priorityBands[priority]; ok {
-		band.len.Add(uint64(lenDelta))
-		band.byteSize.Add(uint64(byteSizeDelta))
-	}
-
-	s.logger.V(logging.TRACE).Info("Reconciled shard stats", "priority", priority,
-		"lenDelta", lenDelta, "byteSizeDelta", byteSizeDelta)
-
-	if s.reconcileFun != nil {
-		s.reconcileFun(lenDelta, byteSizeDelta)
-	}
-}
-
 // ID returns the unique identifier for this shard.
 func (s *registryShard) ID() string { return s.id }
 
 // IsActive returns true if the shard is active and accepting new requests.
+// This is a lock-free read, making it efficient for the hot path.
 func (s *registryShard) IsActive() bool {
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-	return s.isActive
+	return !s.isDraining.Load()
 }
 
-// ManagedQueue retrieves a specific `ManagedQueue` instance from this shard.
+// ManagedQueue retrieves a specific `contracts.ManagedQueue` instance from this shard.
 func (s *registryShard) ManagedQueue(key types.FlowKey) (contracts.ManagedQueue, error) {
 	s.mu.RLock()
 	defer s.mu.RUnlock()
@@ -177,10 +159,9 @@ func (s *registryShard) ManagedQueue(key types.FlowKey) (contracts.ManagedQueue,
 	if !ok {
 		return nil, fmt.Errorf("failed to get managed queue for flow %q: %w", key, contracts.ErrPriorityBandNotFound)
 	}
-	mq, ok := band.queues[key]
+	mq, ok := band.queues[key.ID]
 	if !ok {
-		return nil, fmt.Errorf("failed to get managed queue for flow %q: %w",
-			key, contracts.ErrFlowInstanceNotFound)
+		return nil, fmt.Errorf("failed to get managed queue for flow %q: %w", key, contracts.ErrFlowInstanceNotFound)
 	}
 	return mq, nil
 }
@@ -194,20 +175,18 @@ func (s *registryShard) IntraFlowDispatchPolicy(key types.FlowKey) (framework.In
 	if !ok {
 		return nil, fmt.Errorf("failed to get intra-flow policy for flow %q: %w", key, contracts.ErrPriorityBandNotFound)
 	}
-	mq, ok := band.queues[key]
+	mq, ok := band.queues[key.ID]
 	if !ok {
-		return nil, fmt.Errorf("failed to get intra-flow policy for flow %q: %w",
-			key, contracts.ErrFlowInstanceNotFound)
+		return nil, fmt.Errorf("failed to get intra-flow policy for flow %q: %w", key, contracts.ErrFlowInstanceNotFound)
 	}
-	// The policy is stored on the managed queue.
+	// The policy is stored on the `managedQueue` and is immutable after creation.
 	return mq.dispatchPolicy, nil
 }
 
 // InterFlowDispatchPolicy retrieves a priority band's configured `framework.InterFlowDispatchPolicy`.
-func (s *registryShard) InterFlowDispatchPolicy(priority uint) (framework.InterFlowDispatchPolicy, error) {
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-
+// This read is lock-free as the policy instance is immutable after the shard is initialized.
+func (s *registryShard) InterFlowDispatchPolicy(priority int) (framework.InterFlowDispatchPolicy, error) {
+	// This read is safe because the `priorityBands` map structure is immutable after initialization.
 	band, ok := s.priorityBands[priority]
 	if !ok {
 		return nil, fmt.Errorf("failed to get inter-flow policy for priority %d: %w",
@@ -216,8 +195,8 @@ func (s *registryShard) InterFlowDispatchPolicy(priority uint) (framework.InterF
 	return band.interFlowDispatchPolicy, nil
 }
 
-// PriorityBandAccessor retrieves a read-only accessor for a given priority level.
-func (s *registryShard) PriorityBandAccessor(priority uint) (framework.PriorityBandAccessor, error) {
+// PriorityBandAccessor retrieves a read-only view for a given priority level.
+func (s *registryShard) PriorityBandAccessor(priority int) (framework.PriorityBandAccessor, error) {
 	s.mu.RLock()
 	defer s.mu.RUnlock()
 
@@ -229,40 +208,145 @@ func (s *registryShard) PriorityBandAccessor(priority uint) (framework.PriorityB
 	return &priorityBandAccessor{shard: s, band: band}, nil
 }
 
-// AllOrderedPriorityLevels returns all configured priority levels for this shard, sorted from highest to lowest
-// priority (ascending numerical order).
-func (s *registryShard) AllOrderedPriorityLevels() []uint {
-	// This is cached and read-only, so no lock is needed.
+// AllOrderedPriorityLevels returns a cached, sorted slice of all configured priority levels for this shard.
+// This is a lock-free read.
+func (s *registryShard) AllOrderedPriorityLevels() []int {
 	return s.orderedPriorityLevels
 }
 
-// Stats returns a snapshot of the statistics for this specific shard.
+// Stats returns a snapshot of the aggregated statistics for this specific shard.
+//
+// Note on Concurrency and Consistency: Statistics are aggregated using high-performance, lock-free atomic updates
+// propagated from the underlying `managedQueue` instances. The returned stats represent a near-consistent snapshot of
+// the shard's state. It is not perfectly atomic because the various counters are loaded independently without a global
+// lock.
 func (s *registryShard) Stats() contracts.ShardStats {
+	// Acquire `RLock` only to ensure the config/map structure isn't changing during iteration.
 	s.mu.RLock()
 	defer s.mu.RUnlock()
 
+	// Casts from `int64` to `uint64` are safe because the non-negative invariant is strictly enforced at the
+	// `managedQueue` level.
 	stats := contracts.ShardStats{
+		ID:                   s.id,
+		IsActive:             s.IsActive(),
 		TotalCapacityBytes:   s.config.MaxBytes,
-		TotalByteSize:        s.totalByteSize.Load(),
-		TotalLen:             s.totalLen.Load(),
-		PerPriorityBandStats: make(map[uint]contracts.PriorityBandStats, len(s.priorityBands)),
+		TotalByteSize:        uint64(s.totalByteSize.Load()),
+		TotalLen:             uint64(s.totalLen.Load()),
+		PerPriorityBandStats: make(map[int]contracts.PriorityBandStats, len(s.priorityBands)),
 	}
 
 	for priority, band := range s.priorityBands {
 		stats.PerPriorityBandStats[priority] = contracts.PriorityBandStats{
 			Priority:      priority,
 			PriorityName:  band.config.PriorityName,
-			CapacityBytes: band.config.MaxBytes, // This is the partitioned capacity
-			ByteSize:      band.byteSize.Load(),
-			Len:           band.len.Load(),
+			CapacityBytes: band.config.MaxBytes, // This is the partitioned capacity.
+			ByteSize:      uint64(band.byteSize.Load()),
+			Len:           uint64(band.len.Load()),
 		}
 	}
 	return stats
 }
 
-var _ contracts.RegistryShard = &registryShard{}
+//  --- Internal Administrative/Lifecycle Methods (called by `FlowRegistry`) ---
+
+// synchronizeFlow is the internal administrative method for creating a flow instance on this shard.
+// It is an idempotent "create if not exists" operation.
+func (s *registryShard) synchronizeFlow(
+	spec types.FlowSpecification,
+	policy framework.IntraFlowDispatchPolicy,
+	q framework.SafeQueue,
+) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	key := spec.Key
+
+	// Find the correct priority band. A missing band is an invariant violation, as the `FlowRegistry` should have already
+	// validated this.
+	band, ok := s.priorityBands[key.Priority]
+	if !ok {
+		panic(fmt.Sprintf("invariant violation: attempt to synchronize flow on non-existent priority band %d", key.Priority))
+	}
 
-// --- priorityBandAccessor ---
+	if _, ok := band.queues[key.ID]; ok {
+		return
+	}
+
+	s.logger.V(logging.TRACE).Info("Creating new queue for flow instance.",
+		"flowKey", key, "queueType", q.Name())
+
+	// Create a closure that captures the shard's `isDraining` atomic field.
+	// This provides the queue with a way to check the shard's status without creating a tight coupling or circular
+	// dependency.
+	isDrainingFunc := func() bool {
+		return s.isDraining.Load()
+	}
+
+	mq := newManagedQueue(q, policy, spec.Key, s.logger, s.propagateStatsDelta, isDrainingFunc)
+	band.queues[key.ID] = mq
+}
+
+// deleteFlowLocked removes a queue instance from the shard.
+func (s *registryShard) deleteFlow(key types.FlowKey) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.logger.Info("Deleting queue instance.", "flowKey", key, "flowID", key.ID, "priority", key.Priority)
+	if band, ok := s.priorityBands[key.Priority]; ok {
+		delete(band.queues, key.ID)
+	}
+}
+
+// markAsDraining transitions the shard to a Draining state. This method is lock-free.
+func (s *registryShard) markAsDraining() {
+	s.isDraining.Store(true)
+	s.logger.V(logging.DEBUG).Info("Shard marked as Draining")
+}
+
+// updateConfig atomically replaces the shard's configuration. This is used during scaling events to re-partition
+// capacity allocations.
+func (s *registryShard) updateConfig(newConfig *ShardConfig) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	s.config = newConfig
+	// Update the partitioned config for each priority band as well.
+	for priority, band := range s.priorityBands {
+		newBandConfig, err := newConfig.getBandConfig(priority)
+		if err != nil {
+			// An invariant was violated: a priority exists in the shard but not in the new config.
+			panic(fmt.Errorf("invariant violation: priority band (%d) missing in new shard configuration during update: %w",
+				priority, err))
+		}
+		band.config = *newBandConfig
+	}
+	s.logger.Info("Shard configuration updated")
+}
+
+// --- Internal Callback ---
+
+// propagateStatsDelta is the single point of entry for all statistics changes within the shard.
+// It atomically updates the relevant band's stats, the shard's total stats, and propagates the delta to the parent
+// registry.
+func (s *registryShard) propagateStatsDelta(priority int, lenDelta, byteSizeDelta int64) {
+	// This read is safe because the `priorityBands` map structure is immutable after initialization.
+	band, ok := s.priorityBands[priority]
+	if !ok {
+		// This should be impossible if the `managedQueue` calling this is correctly registered.
+		panic(fmt.Sprintf("invariant violation on shard %s: received stats propagation for unknown priority band (%d)",
+			s.id, priority))
+	}
+
+	band.len.Add(lenDelta)
+	band.byteSize.Add(byteSizeDelta)
+	s.totalLen.Add(lenDelta)
+	s.totalByteSize.Add(byteSizeDelta)
+
+	// Propagate the delta up to the parent registry. This propagation is lock-free and eventually consistent.
+	s.onStatsDelta(priority, lenDelta, byteSizeDelta)
+}
+
+// --- `priorityBandAccessor` ---
 
 // priorityBandAccessor implements `framework.PriorityBandAccessor`. It provides a read-only, concurrent-safe view of a
 // single priority band within a shard.
@@ -271,30 +355,39 @@ type priorityBandAccessor struct {
 	band  *priorityBand
 }
 
+var _ framework.PriorityBandAccessor = &priorityBandAccessor{}
+
 // Priority returns the numerical priority level of this band.
-func (a *priorityBandAccessor) Priority() uint {
-	return a.band.config.Priority
-}
+func (a *priorityBandAccessor) Priority() int { return a.band.config.Priority }
 
 // PriorityName returns the human-readable name of this priority band.
-func (a *priorityBandAccessor) PriorityName() string {
-	return a.band.config.PriorityName
-}
+func (a *priorityBandAccessor) PriorityName() string { return a.band.config.PriorityName }
 
 // FlowKeys returns a slice of all flow keys within this priority band.
-// This is an O(1) operation because the slice is pre-computed and cached.
+//
+// To minimize lock contention, this implementation first snapshots the flow IDs under a read lock and then constructs
+// the final slice of `types.FlowKey` structs outside of the lock.
 func (a *priorityBandAccessor) FlowKeys() []types.FlowKey {
 	a.shard.mu.RLock()
-	defer a.shard.mu.RUnlock()
-	return a.band.flowKeys
+	ids := make([]string, 0, len(a.band.queues))
+	for id := range a.band.queues {
+		ids = append(ids, id)
+	}
+	a.shard.mu.RUnlock()
+
+	flowKeys := make([]types.FlowKey, len(ids))
+	for i, id := range ids {
+		flowKeys[i] = types.FlowKey{ID: id, Priority: a.Priority()}
+	}
+	return flowKeys
 }
 
-// Queue returns a `framework.FlowQueueAccessor` for the specified `ID` within this priority band.
+// Queue returns a `framework.FlowQueueAccessor` for the specified logical `ID` within this priority band.
 func (a *priorityBandAccessor) Queue(id string) framework.FlowQueueAccessor {
 	a.shard.mu.RLock()
 	defer a.shard.mu.RUnlock()
 
-	mq, ok := a.band.queues[types.FlowKey{ID: id, Priority: a.Priority()}]
+	mq, ok := a.band.queues[id]
 	if !ok {
 		return nil
 	}
@@ -302,18 +395,21 @@ func (a *priorityBandAccessor) Queue(id string) framework.FlowQueueAccessor {
 }
 
 // IterateQueues executes the given `callback` for each `framework.FlowQueueAccessor` in this priority band.
-// The callback is executed under the shard's read lock, so it should be efficient and non-blocking.
-// If the callback returns false, iteration stops.
+//
+// To minimize lock contention, this implementation snapshots the queue accessors under a read lock and then executes
+// the callback on the snapshot, outside of the lock. This ensures that a potentially slow policy (the callback) does
+// not block other operations on the shard.
 func (a *priorityBandAccessor) IterateQueues(callback func(queue framework.FlowQueueAccessor) bool) {
 	a.shard.mu.RLock()
-	defer a.shard.mu.RUnlock()
+	accessors := make([]framework.FlowQueueAccessor, 0, len(a.band.queues))
+	for _, mq := range a.band.queues {
+		accessors = append(accessors, mq.FlowQueueAccessor())
+	}
+	a.shard.mu.RUnlock()
 
-	for _, key := range a.band.flowKeys {
-		mq := a.band.queues[key]
-		if !callback(mq.FlowQueueAccessor()) {
+	for _, accessor := range accessors {
+		if !callback(accessor) {
 			return
 		}
 	}
 }
-
-var _ framework.PriorityBandAccessor = &priorityBandAccessor{}
diff --git a/pkg/epp/flowcontrol/types/errors.go b/pkg/epp/flowcontrol/types/errors.go
index 4da47c1..8c966bb 100644
--- a/pkg/epp/flowcontrol/types/errors.go
+++ b/pkg/epp/flowcontrol/types/errors.go
@@ -43,14 +43,8 @@ var (
 // The following errors can occur before a request is formally added to a `framework.SafeQueue`. When returned by
 // `FlowController.EnqueueAndWait()`, these specific errors will typically be wrapped by `ErrRejected`.
 var (
-	// ErrNilRequest indicates that a nil `types.FlowControlRequest` was provided.
-	ErrNilRequest = errors.New("FlowControlRequest cannot be nil")
-
-	// ErrFlowIDEmpty indicates that a flow ID was empty when one was required.
-	ErrFlowIDEmpty = errors.New("flow ID cannot be empty")
-
 	// ErrQueueAtCapacity indicates that a request could not be enqueued because queue capacity limits were met.
-	ErrQueueAtCapacity = errors.New("queue at capacity and displacement failed to make space")
+	ErrQueueAtCapacity = errors.New("queue at capacity")
 )
 
 // --- Post-Enqueue Eviction Errors ---
@@ -71,10 +65,10 @@ var (
 // --- General `controller.FlowController` Errors ---
 
 var (
-	// ErrFlowControllerShutdown indicates that an operation could not complete or an item was evicted because the
-	// `controller.FlowController` is shutting down or has stopped.
+	// ErrFlowControllerNotRunning indicates that an operation could not complete or an item was evicted because the
+	// `controller.FlowController` is not running or is in the process of shutting down.
 	//
 	// When returned by `FlowController.EnqueueAndWait()`, this will be wrapped by `ErrRejected` (if rejection happens
 	// before internal queuing) or `ErrEvicted` (if eviction happens after internal queuing).
-	ErrFlowControllerShutdown = errors.New("FlowController is shutting down")
+	ErrFlowControllerNotRunning = errors.New("flow controller is not running")
 )
diff --git a/pkg/epp/flowcontrol/types/flow.go b/pkg/epp/flowcontrol/types/flow.go
index 0d8a1b8..2af2d5b 100644
--- a/pkg/epp/flowcontrol/types/flow.go
+++ b/pkg/epp/flowcontrol/types/flow.go
@@ -17,7 +17,7 @@ limitations under the License.
 package types
 
 import (
-	"fmt"
+	"strconv"
 	"strings"
 )
 
@@ -41,14 +41,18 @@ type FlowKey struct {
 	//
 	// Because the `FlowKey` is immutable, changing the priority of traffic requires using a new `FlowKey`; the old flow
 	// instance will be automatically garbage collected by the registry when it becomes idle.
-	Priority uint
+	Priority int
+}
+
+func (k FlowKey) String() string {
+	return k.ID + ":" + strconv.FormatUint(uint64(k.Priority), 10)
 }
 
 // Compare provides a stable comparison function for two FlowKey instances, suitable for use with sorting algorithms.
-// It returns -1 if the key is less than the other, 0 if they are equal, and 1 if the key is greater than the other.
-// The comparison is performed first by Priority (descending) and then by ID (ascending).
+// It returns 1 if the key is less than the other, 0 if they are equal, and -1 if the key is greater than the other.
+// The comparison is performed first by `Priority` (ascending, higher priority first) and then by `ID` (ascending).
 func (k FlowKey) Compare(other FlowKey) int {
-	if k.Priority > other.Priority {
+	if k.Priority > other.Priority { // Higher number means higher priority
 		return -1
 	}
 	if k.Priority < other.Priority {
@@ -57,10 +61,6 @@ func (k FlowKey) Compare(other FlowKey) int {
 	return strings.Compare(k.ID, other.ID)
 }
 
-func (k FlowKey) String() string {
-	return fmt.Sprintf("%s::%d", k.ID, k.Priority)
-}
-
 // FlowSpecification defines the complete configuration for a single logical flow instance, which is uniquely identified
 // by its immutable `Key`.
 //
diff --git a/pkg/epp/flowcontrol/types/mocks/mocks.go b/pkg/epp/flowcontrol/types/mocks/mocks.go
index dbef031..c52c5c2 100644
--- a/pkg/epp/flowcontrol/types/mocks/mocks.go
+++ b/pkg/epp/flowcontrol/types/mocks/mocks.go
@@ -22,16 +22,18 @@ import (
 	"context"
 	"time"
 
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
 )
 
 // MockFlowControlRequest provides a mock implementation of the `types.FlowControlRequest` interface.
 type MockFlowControlRequest struct {
-	Ctx                  context.Context
-	FlowKeyV             types.FlowKey
-	ByteSizeV            uint64
-	InitialEffectiveTTLV time.Duration
-	IDV                  string
+	Ctx                         context.Context
+	FlowKeyV                    types.FlowKey
+	ByteSizeV                   uint64
+	InitialEffectiveTTLV        time.Duration
+	IDV                         string
+	CandidatePodsForSchedulingV []*metrics.FakePodMetrics
 }
 
 // NewMockFlowControlRequest creates a new `MockFlowControlRequest` instance.
@@ -58,6 +60,14 @@ func (m *MockFlowControlRequest) ByteSize() uint64                   { return m.
 func (m *MockFlowControlRequest) InitialEffectiveTTL() time.Duration { return m.InitialEffectiveTTLV }
 func (m *MockFlowControlRequest) ID() string                         { return m.IDV }
 
+func (m *MockFlowControlRequest) CandidatePodsForScheduling() []metrics.PodMetrics {
+	pods := make([]metrics.PodMetrics, 0, len(m.CandidatePodsForSchedulingV))
+	for i, pod := range m.CandidatePodsForSchedulingV {
+		pods[i] = pod
+	}
+	return pods
+}
+
 var _ types.FlowControlRequest = &MockFlowControlRequest{}
 
 // MockQueueItemHandle provides a mock implementation of the `types.QueueItemHandle` interface.
diff --git a/pkg/epp/flowcontrol/types/request.go b/pkg/epp/flowcontrol/types/request.go
index 7569407..255d3bc 100644
--- a/pkg/epp/flowcontrol/types/request.go
+++ b/pkg/epp/flowcontrol/types/request.go
@@ -19,6 +19,8 @@ package types
 import (
 	"context"
 	"time"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 )
 
 // FlowControlRequest is the contract for an incoming request submitted to the `controller.FlowController`. It
@@ -49,6 +51,11 @@ type FlowControlRequest interface {
 	// applied.
 	InitialEffectiveTTL() time.Duration
 
+	// CandidatePodsForScheduling passes through a set of candidate pods a request may be admitted to.
+	// This is necessary for invoking `contracts.SaturationDetector.IsSaturated`, but it is otherwise unused in the Flow
+	// Control system.
+	CandidatePodsForScheduling() []metrics.PodMetrics
+
 	// ID returns an optional, user-facing unique identifier for this specific request. It is intended for logging,
 	// tracing, and observability. The `controller.FlowController` does not use this ID for dispatching decisions; it uses
 	// the internal, opaque `QueueItemHandle`.
@@ -92,7 +99,8 @@ type QueueItemAccessor interface {
 	OriginalRequest() FlowControlRequest
 
 	// EnqueueTime is the timestamp when the item was logically accepted by the `controller.FlowController` for queuing
-	// (i.e., when `controller.FlowController.EnqueueAndWait()` was called).
+	// (i.e., when `controller.FlowController.EnqueueAndWait()` was called). It does not reflect the time the request
+	// landed in a `framework.SafeQueue` instance.
 	EnqueueTime() time.Time
 
 	// EffectiveTTL is the actual Time-To-Live assigned to this item by the `controller.FlowController`, taking into
diff --git a/pkg/epp/handlers/response.go b/pkg/epp/handlers/response.go
index 0ccaf81..7dfaf3b 100644
--- a/pkg/epp/handlers/response.go
+++ b/pkg/epp/handlers/response.go
@@ -19,6 +19,7 @@ package handlers
 import (
 	"context"
 	"encoding/json"
+	"fmt"
 	"strings"
 
 	configPb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
@@ -39,8 +40,7 @@ func (s *StreamingServer) HandleResponseBody(ctx context.Context, reqCtx *Reques
 	logger := log.FromContext(ctx)
 	responseBytes, err := json.Marshal(response)
 	if err != nil {
-		logger.V(logutil.DEFAULT).Error(err, "error marshalling responseBody")
-		return reqCtx, err
+		return reqCtx, fmt.Errorf("error marshalling responseBody - %w", err)
 	}
 	if response["usage"] != nil {
 		usg := response["usage"].(map[string]any)
diff --git a/pkg/epp/handlers/server.go b/pkg/epp/handlers/server.go
index 89e09f9..ddfb331 100644
--- a/pkg/epp/handlers/server.go
+++ b/pkg/epp/handlers/server.go
@@ -26,6 +26,7 @@ import (
 	extProcPb "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
 	envoyTypePb "github.com/envoyproxy/go-control-plane/envoy/type/v3"
 	"github.com/go-logr/logr"
+	"github.com/google/uuid"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 	"sigs.k8s.io/controller-runtime/pkg/log"
@@ -176,9 +177,6 @@ func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer)
 			return nil
 		}
 		if recvErr != nil {
-			// This error occurs very frequently, though it doesn't seem to have any impact.
-			// TODO Figure out if we can remove this noise.
-			logger.V(logutil.DEFAULT).Error(err, "Cannot receive stream request")
 			return status.Errorf(codes.Unknown, "cannot receive stream request: %v", err)
 		}
 
@@ -186,11 +184,18 @@ func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer)
 
 		switch v := req.Request.(type) {
 		case *extProcPb.ProcessingRequest_RequestHeaders:
-			if requestID := requtil.ExtractHeaderValue(v, requtil.RequestIdHeaderKey); len(requestID) > 0 {
-				logger = logger.WithValues(requtil.RequestIdHeaderKey, requestID)
-				loggerTrace = logger.V(logutil.TRACE)
-				ctx = log.IntoContext(ctx, logger)
+			requestID := requtil.ExtractHeaderValue(v, requtil.RequestIdHeaderKey)
+			// request ID is a must for maintaining a state per request in plugins that hold internal state and use PluginState.
+			// if request id was not supplied as a header, we generate it ourselves.
+			if len(requestID) == 0 {
+				requestID = uuid.NewString()
+				loggerTrace.Info("RequestID header is not found in the request, generated a request id")
+				reqCtx.Request.Headers[requtil.RequestIdHeaderKey] = requestID // update in headers so director can consume it
 			}
+			logger = logger.WithValues(requtil.RequestIdHeaderKey, requestID)
+			loggerTrace = logger.V(logutil.TRACE)
+			ctx = log.IntoContext(ctx, logger)
+
 			err = s.HandleRequestHeaders(reqCtx, v)
 		case *extProcPb.ProcessingRequest_RequestBody:
 			loggerTrace.Info("Incoming body chunk", "EoS", v.RequestBody.EndOfStream)
diff --git a/pkg/epp/metrics/metrics.go b/pkg/epp/metrics/metrics.go
index acb2f03..cefc4d4 100644
--- a/pkg/epp/metrics/metrics.go
+++ b/pkg/epp/metrics/metrics.go
@@ -31,36 +31,36 @@ import (
 )
 
 const (
-	InferenceModelComponent = "inference_model"
-	InferencePoolComponent  = "inference_pool"
-	InferenceExtension      = "inference_extension"
+	InferenceObjectiveComponent = "inference_objective"
+	InferencePoolComponent      = "inference_pool"
+	InferenceExtension          = "inference_extension"
 )
 
 var (
-	// Inference Model Metrics
+	// Inference Objective Metrics
 	requestCounter = prometheus.NewCounterVec(
 		prometheus.CounterOpts{
-			Subsystem: InferenceModelComponent,
+			Subsystem: InferenceObjectiveComponent,
 			Name:      "request_total",
-			Help:      metricsutil.HelpMsgWithStability("Counter of inference model requests broken out for each model and target model.", compbasemetrics.ALPHA),
+			Help:      metricsutil.HelpMsgWithStability("Counter of inference objective requests broken out for each model and target model.", compbasemetrics.ALPHA),
 		},
 		[]string{"model_name", "target_model_name"},
 	)
 
 	requestErrCounter = prometheus.NewCounterVec(
 		prometheus.CounterOpts{
-			Subsystem: InferenceModelComponent,
+			Subsystem: InferenceObjectiveComponent,
 			Name:      "request_error_total",
-			Help:      metricsutil.HelpMsgWithStability("Counter of inference model requests errors broken out for each model and target model.", compbasemetrics.ALPHA),
+			Help:      metricsutil.HelpMsgWithStability("Counter of inference objective requests errors broken out for each model and target model.", compbasemetrics.ALPHA),
 		},
 		[]string{"model_name", "target_model_name", "error_code"},
 	)
 
 	requestLatencies = prometheus.NewHistogramVec(
 		prometheus.HistogramOpts{
-			Subsystem: InferenceModelComponent,
+			Subsystem: InferenceObjectiveComponent,
 			Name:      "request_duration_seconds",
-			Help:      metricsutil.HelpMsgWithStability("Inference model response latency distribution in seconds for each model and target model.", compbasemetrics.ALPHA),
+			Help:      metricsutil.HelpMsgWithStability("Inference objective response latency distribution in seconds for each model and target model.", compbasemetrics.ALPHA),
 			Buckets: []float64{
 				0.005, 0.025, 0.05, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 1.25, 1.5, 2, 3,
 				4, 5, 6, 8, 10, 15, 20, 30, 45, 60, 120, 180, 240, 300, 360, 480, 600, 900, 1200, 1800, 2700, 3600,
@@ -71,9 +71,9 @@ var (
 
 	requestSizes = prometheus.NewHistogramVec(
 		prometheus.HistogramOpts{
-			Subsystem: InferenceModelComponent,
+			Subsystem: InferenceObjectiveComponent,
 			Name:      "request_sizes",
-			Help:      metricsutil.HelpMsgWithStability("Inference model requests size distribution in bytes for each model and target model.", compbasemetrics.ALPHA),
+			Help:      metricsutil.HelpMsgWithStability("Inference objective requests size distribution in bytes for each model and target model.", compbasemetrics.ALPHA),
 			// Use buckets ranging from 1000 bytes (1KB) to 10^9 bytes (1GB).
 			Buckets: []float64{
 				64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, // More fine-grained up to 64KB
@@ -86,9 +86,9 @@ var (
 
 	responseSizes = prometheus.NewHistogramVec(
 		prometheus.HistogramOpts{
-			Subsystem: InferenceModelComponent,
+			Subsystem: InferenceObjectiveComponent,
 			Name:      "response_sizes",
-			Help:      metricsutil.HelpMsgWithStability("Inference model responses size distribution in bytes for each model and target model.", compbasemetrics.ALPHA),
+			Help:      metricsutil.HelpMsgWithStability("Inference objective responses size distribution in bytes for each model and target model.", compbasemetrics.ALPHA),
 			// Most models have a response token < 8192 tokens. Each token, in average, has 4 characters.
 			// 8192 * 4 = 32768.
 			Buckets: []float64{1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32778, 65536},
@@ -98,9 +98,9 @@ var (
 
 	inputTokens = prometheus.NewHistogramVec(
 		prometheus.HistogramOpts{
-			Subsystem: InferenceModelComponent,
+			Subsystem: InferenceObjectiveComponent,
 			Name:      "input_tokens",
-			Help:      metricsutil.HelpMsgWithStability("Inference model input token count distribution for requests in each model.", compbasemetrics.ALPHA),
+			Help:      metricsutil.HelpMsgWithStability("Inference objective input token count distribution for requests in each model.", compbasemetrics.ALPHA),
 			// Most models have a input context window less than 1 million tokens.
 			Buckets: []float64{1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32778, 65536, 131072, 262144, 524288, 1048576},
 		},
@@ -109,9 +109,9 @@ var (
 
 	outputTokens = prometheus.NewHistogramVec(
 		prometheus.HistogramOpts{
-			Subsystem: InferenceModelComponent,
+			Subsystem: InferenceObjectiveComponent,
 			Name:      "output_tokens",
-			Help:      metricsutil.HelpMsgWithStability("Inference model output token count distribution for requests in each model.", compbasemetrics.ALPHA),
+			Help:      metricsutil.HelpMsgWithStability("Inference objective output token count distribution for requests in each model.", compbasemetrics.ALPHA),
 			// Most models generates output less than 8192 tokens.
 			Buckets: []float64{1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192},
 		},
@@ -120,9 +120,9 @@ var (
 
 	runningRequests = prometheus.NewGaugeVec(
 		prometheus.GaugeOpts{
-			Subsystem: InferenceModelComponent,
+			Subsystem: InferenceObjectiveComponent,
 			Name:      "running_requests",
-			Help:      metricsutil.HelpMsgWithStability("Inference model number of running requests in each model.", compbasemetrics.ALPHA),
+			Help:      metricsutil.HelpMsgWithStability("Inference objective number of running requests in each model.", compbasemetrics.ALPHA),
 		},
 		[]string{"model_name"},
 	)
@@ -130,9 +130,9 @@ var (
 	// NTPOT - Normalized Time Per Output Token
 	NormalizedTimePerOutputToken = prometheus.NewHistogramVec(
 		prometheus.HistogramOpts{
-			Subsystem: InferenceModelComponent,
+			Subsystem: InferenceObjectiveComponent,
 			Name:      "normalized_time_per_output_token_seconds",
-			Help:      metricsutil.HelpMsgWithStability("Inference model latency divided by number of output tokens in seconds for each model and target model.", compbasemetrics.ALPHA),
+			Help:      metricsutil.HelpMsgWithStability("Inference objective latency divided by number of output tokens in seconds for each model and target model.", compbasemetrics.ALPHA),
 			// From few milliseconds per token to multiple seconds per token
 			Buckets: []float64{
 				0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0,
diff --git a/pkg/epp/plugins/plugin_state.go b/pkg/epp/plugins/plugin_state.go
index 2da3557..0281900 100644
--- a/pkg/epp/plugins/plugin_state.go
+++ b/pkg/epp/plugins/plugin_state.go
@@ -51,7 +51,7 @@ func NewPluginState(ctx context.Context) *PluginState {
 // Note: PluginState uses a sync.Map to back the storage, because it is thread safe.
 // It's aimed to optimize for the "write once and read many times" scenarios.
 type PluginState struct {
-	// key: RequestID, value: map[StateKey]StateData
+	// key: RequestID, value: sync.Map[StateKey]StateData
 	storage sync.Map
 	// key: RequestID, value: time.Time
 	requestToLastAccessTime sync.Map
@@ -66,9 +66,9 @@ func (s *PluginState) Read(requestID string, key StateKey) (StateData, error) {
 		return nil, ErrNotFound
 	}
 
-	stateData := stateMap.(map[StateKey]StateData)
-	if value, ok := stateData[key]; ok {
-		return value, nil
+	stateData := stateMap.(*sync.Map)
+	if value, ok := stateData.Load(key); ok {
+		return value.(StateData), nil
 	}
 
 	return nil, ErrNotFound
@@ -77,15 +77,15 @@ func (s *PluginState) Read(requestID string, key StateKey) (StateData, error) {
 // Write stores the given "val" in PluginState with the given "key" in the context of the given "requestID".
 func (s *PluginState) Write(requestID string, key StateKey, val StateData) {
 	s.requestToLastAccessTime.Store(requestID, time.Now())
-	var stateData map[StateKey]StateData
+	var stateData *sync.Map
 	stateMap, ok := s.storage.Load(requestID)
 	if ok {
-		stateData = stateMap.(map[StateKey]StateData)
+		stateData = stateMap.(*sync.Map)
 	} else {
-		stateData = map[StateKey]StateData{}
+		stateData = &sync.Map{}
 	}
 
-	stateData[key] = val
+	stateData.Store(key, val)
 
 	s.storage.Store(requestID, stateData)
 }
diff --git a/pkg/epp/requestcontrol/director.go b/pkg/epp/requestcontrol/director.go
index 1435c01..a3e2d6d 100644
--- a/pkg/epp/requestcontrol/director.go
+++ b/pkg/epp/requestcontrol/director.go
@@ -29,10 +29,10 @@ import (
 
 	"sigs.k8s.io/controller-runtime/pkg/log"
 
+	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
 	"sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend"
 	backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datastore"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/handlers"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metadata"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metrics"
@@ -42,6 +42,13 @@ import (
 	requtil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/request"
 )
 
+// Datastore defines the interface required by the Director.
+type Datastore interface {
+	PoolGet() (*v1.InferencePool, error)
+	ObjectiveGet(modelName string) *v1alpha2.InferenceObjective
+	PodList(predicate func(backendmetrics.PodMetrics) bool) []backendmetrics.PodMetrics
+}
+
 // Scheduler defines the interface required by the Director for scheduling.
 type Scheduler interface {
 	Schedule(ctx context.Context, request *schedulingtypes.LLMRequest, candidatePods []schedulingtypes.Pod) (result *schedulingtypes.SchedulingResult, err error)
@@ -49,23 +56,24 @@ type Scheduler interface {
 
 // SaturationDetector provides a signal indicating whether the backends are considered saturated.
 type SaturationDetector interface {
-	IsSaturated(ctx context.Context) bool
+	IsSaturated(ctx context.Context, candidatePods []backendmetrics.PodMetrics) bool
 }
 
 // NewDirectorWithConfig creates a new Director instance with all dependencies.
-func NewDirectorWithConfig(datastore datastore.Datastore, scheduler Scheduler, saturationDetector SaturationDetector, config *Config) *Director {
+func NewDirectorWithConfig(datastore Datastore, scheduler Scheduler, saturationDetector SaturationDetector, config *Config) *Director {
 	return &Director{
 		datastore:           datastore,
 		scheduler:           scheduler,
 		saturationDetector:  saturationDetector,
 		preRequestPlugins:   config.preRequestPlugins,
 		postResponsePlugins: config.postResponsePlugins,
+		defaultPriority:     0, // define default priority explicitly
 	}
 }
 
 // Director orchestrates the request handling flow, including scheduling.
 type Director struct {
-	datastore           datastore.Datastore
+	datastore           Datastore
 	scheduler           Scheduler
 	saturationDetector  SaturationDetector
 	preRequestPlugins   []PreRequest
@@ -76,17 +84,12 @@ type Director struct {
 	defaultPriority int
 }
 
-// HandleRequest orchestrates the request lifecycle:
-//  1. Parses request details.
-//  2. Calls admitRequest for admission control.
-//  3. Calls Scheduler.Schedule if request is approved.
-//  4. Calls prepareRequest to populate RequestContext with result and call PreRequest plugins.
-//
+// HandleRequest orchestrates the request lifecycle.
 // It always returns the requestContext even in the error case, as the request context is used in error handling.
 func (d *Director) HandleRequest(ctx context.Context, reqCtx *handlers.RequestContext) (*handlers.RequestContext, error) {
 	logger := log.FromContext(ctx)
 
-	// --- 1. Parse Request, Resolve Target Models, and Determine Parameters ---
+	// Parse Request, Resolve Target Models, and Determine Parameters
 	requestBodyMap := reqCtx.Request.Body
 	var ok bool
 	reqCtx.IncomingModelName, ok = requestBodyMap["model"].(string)
@@ -100,10 +103,11 @@ func (d *Director) HandleRequest(ctx context.Context, reqCtx *handlers.RequestCo
 	}
 	reqCtx.Request.Body["model"] = reqCtx.TargetModelName
 
-	prompt, err := requtil.ExtractPromptFromRequestBody(requestBodyMap)
+	requestBody, err := requtil.ExtractRequestBody(reqCtx.Request.Body)
 	if err != nil {
-		return reqCtx, err
+		return reqCtx, errutil.Error{Code: errutil.BadRequest, Msg: fmt.Errorf("failed to extract request data: %w", err).Error()}
 	}
+
 	infObjective := d.datastore.ObjectiveGet(reqCtx.ObjectiveKey)
 	if infObjective == nil {
 		logger.V(logutil.VERBOSE).Info("No associated InferenceObjective found, using default", "objectiveKey", reqCtx.ObjectiveKey)
@@ -121,7 +125,7 @@ func (d *Director) HandleRequest(ctx context.Context, reqCtx *handlers.RequestCo
 	reqCtx.SchedulingRequest = &schedulingtypes.LLMRequest{
 		RequestId:   reqCtx.Request.Headers[requtil.RequestIdHeaderKey],
 		TargetModel: reqCtx.TargetModelName,
-		Prompt:      prompt,
+		Body:        requestBody,
 		Headers:     reqCtx.Request.Headers,
 	}
 
@@ -130,22 +134,23 @@ func (d *Director) HandleRequest(ctx context.Context, reqCtx *handlers.RequestCo
 	ctx = log.IntoContext(ctx, logger)
 	logger.V(logutil.DEBUG).Info("LLM request assembled")
 
-	// --- 2. Admission Control check --
-	if err := d.admitRequest(ctx, *infObjective.Spec.Priority, reqCtx.FairnessID); err != nil {
-		return reqCtx, err
-	}
-
-	// --- 3. Call Scheduler (with the relevant candidate pods) ---
+	// Get candidate pods for scheduling
 	candidatePods := d.getCandidatePodsForScheduling(ctx, reqCtx.Request.Metadata)
 	if len(candidatePods) == 0 {
 		return reqCtx, errutil.Error{Code: errutil.ServiceUnavailable, Msg: "failed to find candidate pods for serving the request"}
 	}
-	result, err := d.scheduler.Schedule(ctx, reqCtx.SchedulingRequest, candidatePods)
+
+	// Admission Control check
+	if err := d.admitRequest(ctx, candidatePods, *infObjective.Spec.Priority, reqCtx.FairnessID); err != nil {
+		return reqCtx, err
+	}
+
+	result, err := d.scheduler.Schedule(ctx, reqCtx.SchedulingRequest, d.toSchedulerPodMetrics(candidatePods))
 	if err != nil {
 		return reqCtx, errutil.Error{Code: errutil.InferencePoolResourceExhausted, Msg: fmt.Errorf("failed to find target pod: %w", err).Error()}
 	}
 
-	// --- 4. Prepare Request (Populates RequestContext and call PreRequest plugins) ---
+	// Prepare Request (Populates RequestContext and call PreRequest plugins)
 	// Insert target endpoint to instruct Envoy to route requests to the specified target pod and attach the port number.
 	// Invoke PreRequest registered plugins.
 	reqCtx, err = d.prepareRequest(ctx, reqCtx, result)
@@ -156,52 +161,27 @@ func (d *Director) HandleRequest(ctx context.Context, reqCtx *handlers.RequestCo
 	return reqCtx, nil
 }
 
-// admitRequest handles admission control to decide whether or not to accept the request
-// based on the request priority and system saturation state.
-func (d *Director) admitRequest(ctx context.Context, requestPriority int, fairnessID string) error {
-	logger := log.FromContext(ctx)
-
-	logger.V(logutil.TRACE).Info("Entering Flow Control", "priority", requestPriority, "fairnessID", fairnessID)
-
-	// This will be removed in favor of a more robust implementation (Flow Control) in the very near future.
-	// TODO: Make this a configurable value.
-	// Tracking issue https://github.com/kubernetes-sigs/gateway-api-inference-extension/issues/1347
-	if requestPriority >= 0 {
-		logger.V(logutil.TRACE).Info("Non-sheddable request bypassing saturation check.")
-		return nil
-	}
-
-	if d.saturationDetector.IsSaturated(ctx) { // Assuming non-nil Saturation Detector
-		return errutil.Error{
-			Code: errutil.InferencePoolResourceExhausted,
-			Msg:  "system saturated, sheddable request dropped",
-		}
-	}
-
-	return nil
-}
-
 // getCandidatePodsForScheduling gets the list of relevant endpoints for the scheduling cycle from the datastore.
 // according to EPP protocol, if "x-gateway-destination-endpoint-subset" is set on the request metadata and specifies
 // a subset of endpoints, only these endpoints will be considered as candidates for the scheduler.
 // Snapshot pod metrics from the datastore to:
 // 1. Reduce concurrent access to the datastore.
 // 2. Ensure consistent data during the scheduling operation of a request between all scheduling cycles.
-func (d *Director) getCandidatePodsForScheduling(ctx context.Context, requestMetadata map[string]any) []schedulingtypes.Pod {
+func (d *Director) getCandidatePodsForScheduling(ctx context.Context, requestMetadata map[string]any) []backendmetrics.PodMetrics {
 	loggerTrace := log.FromContext(ctx).V(logutil.TRACE)
 
 	subsetMap, found := requestMetadata[metadata.SubsetFilterNamespace].(map[string]any)
 	if !found {
-		return d.toSchedulerPodMetrics(d.datastore.PodList(backendmetrics.AllPodsPredicate))
+		return d.datastore.PodList(backendmetrics.AllPodsPredicate)
 	}
 
 	// Check if endpoint key is present in the subset map and ensure there is at least one value
 	endpointSubsetList, found := subsetMap[metadata.SubsetFilterKey].([]any)
 	if !found {
-		return d.toSchedulerPodMetrics(d.datastore.PodList(backendmetrics.AllPodsPredicate))
+		return d.datastore.PodList(backendmetrics.AllPodsPredicate)
 	} else if len(endpointSubsetList) == 0 {
 		loggerTrace.Info("found empty subset filter in request metadata, filtering all pods")
-		return []schedulingtypes.Pod{}
+		return []backendmetrics.PodMetrics{}
 	}
 
 	// Create a map of endpoint addresses for easy lookup
@@ -214,7 +194,7 @@ func (d *Director) getCandidatePodsForScheduling(ctx context.Context, requestMet
 	}
 
 	podTotalCount := 0
-	podFitleredList := d.datastore.PodList(func(pm backendmetrics.PodMetrics) bool {
+	podFilteredList := d.datastore.PodList(func(pm backendmetrics.PodMetrics) bool {
 		podTotalCount++
 		if _, found := endpoints[pm.GetPod().Address]; found {
 			return true
@@ -222,9 +202,34 @@ func (d *Director) getCandidatePodsForScheduling(ctx context.Context, requestMet
 		return false
 	})
 
-	loggerTrace.Info("filtered candidate pods by subset filtering", "podTotalCount", podTotalCount, "filteredCount", len(podFitleredList))
+	loggerTrace.Info("filtered candidate pods by subset filtering", "podTotalCount", podTotalCount, "filteredCount", len(podFilteredList))
+
+	return podFilteredList
+}
 
-	return d.toSchedulerPodMetrics(podFitleredList)
+// admitRequest handles admission control to decide whether or not to accept the request
+// based on the request priority and saturation state.
+func (d *Director) admitRequest(ctx context.Context, candidatePods []backendmetrics.PodMetrics, requestPriority int, fairnessID string) error {
+	loggerTrace := log.FromContext(ctx).V(logutil.TRACE)
+
+	loggerTrace.Info("Entering Flow Control", "priority", requestPriority, "fairnessID", fairnessID)
+
+	// This will be removed in favor of a more robust implementation (Flow Control) in the very near future.
+	// TODO: Make this a configurable value.
+	// Tracking issue https://github.com/kubernetes-sigs/gateway-api-inference-extension/issues/1347
+	if requestPriority >= 0 {
+		loggerTrace.Info("Non-sheddable request bypassing saturation check.")
+		return nil
+	}
+
+	if d.saturationDetector.IsSaturated(ctx, candidatePods) {
+		return errutil.Error{
+			Code: errutil.InferencePoolResourceExhausted,
+			Msg:  "system saturated, sheddable request dropped",
+		}
+	}
+
+	return nil
 }
 
 // prepareRequest populates the RequestContext and calls the registered PreRequest plugins
diff --git a/pkg/epp/saturationdetector/saturationdetector.go b/pkg/epp/saturationdetector/saturationdetector.go
index bc47ecd..46b94b2 100644
--- a/pkg/epp/saturationdetector/saturationdetector.go
+++ b/pkg/epp/saturationdetector/saturationdetector.go
@@ -17,11 +17,10 @@ limitations under the License.
 // Package saturationdetector implements a mechanism to determine if the
 // backend model servers are considered saturated based on observed metrics.
 //
-// The current implementation provides a global saturation signal (IsSaturated)
+// The current implementation provides a saturation signal (IsSaturated)
 // primarily based on backend queue depths and KV cache utilization, reflecting
 // the saturation signals previously used by the Scheduler before the
-// introduction of the FlowController. It fetches live metrics from the
-// provided Datastore.
+// introduction of the FlowController.
 //
 // TODO: Explore more advanced saturation signals in the future, such as:
 //   - Latency-objective-based saturation.
@@ -61,39 +60,21 @@ type Config struct {
 	MetricsStalenessThreshold time.Duration
 }
 
-// Datastore provides an interface to access backend pod metrics.
-type Datastore interface {
-	PodList(predicate func(backendmetrics.PodMetrics) bool) []backendmetrics.PodMetrics
-}
-
-// Detector determines system saturation based on metrics from the Datastore.
-//
-// The Detector currently holds a direct dependency on a Datastore interface.
-// This design choice was made to encapsulate the logic of fetching and
-// interpreting metrics for saturation, thereby simplifying the dependencies
-// for primary consumers like the FlowController--to be added soon--(which
-// would otherwise need to manage Datastore interactions itself).
-// This architectural decision may be revisited in the future if a more
-// decoupled approach (e.g., passing metrics directly to IsSaturated) proves
-// more beneficial.
+// Detector determines system saturation based on metrics of the given candidate pods.
 type Detector struct {
-	datastore Datastore
-	config    *Config
+	config *Config
 }
 
 // NewDetector creates a new SaturationDetector.
-// The datastore is expected to provide access to live/recently-updated pod
-// metrics.
 // The config provides the thresholds for determining saturation.
-func NewDetector(config *Config, datastore Datastore, logger logr.Logger) *Detector {
+func NewDetector(config *Config, logger logr.Logger) *Detector {
 	logger.WithName(loggerName).V(logutil.DEFAULT).Info("Creating new SaturationDetector",
 		"queueDepthThreshold", config.QueueDepthThreshold,
 		"kvCacheUtilThreshold", config.KVCacheUtilThreshold,
 		"metricsStalenessThreshold", config.MetricsStalenessThreshold.String())
 
 	return &Detector{
-		datastore: datastore,
-		config:    config,
+		config: config,
 	}
 }
 
@@ -104,20 +85,10 @@ func NewDetector(config *Config, datastore Datastore, logger logr.Logger) *Detec
 //  2. WaitingQueueSize <= QueueDepthThreshold.
 //  3. KVCacheUsagePercent <= KVCacheUtilThreshold.
 //
-// If no pods are found in the datastore, the system is considered saturated
-// (no capacity).
-func (d *Detector) IsSaturated(ctx context.Context) bool {
-	logger := log.FromContext(ctx).WithName(loggerName)
-	// TODO: filter out stale metrics here if needed.
-	allPodsMetrics := d.datastore.PodList(backendmetrics.AllPodsPredicate)
-	if len(allPodsMetrics) == 0 {
-		logger.V(logutil.VERBOSE).Info("No pods found in datastore; system is considered SATURATED (no capacity).")
-		// If there are no pods, there is no capacity to serve requests.
-		// Treat this as a saturated state to enable FlowController queuing.
-		return true
-	}
-
-	for _, podMetric := range allPodsMetrics {
+// This function is called with the relevant pods for the current request.
+func (d *Detector) IsSaturated(ctx context.Context, candidatePods []backendmetrics.PodMetrics) bool {
+	logger := log.FromContext(ctx)
+	for _, podMetric := range candidatePods {
 		metrics := podMetric.GetMetrics()
 		podNn := "unknown-pod"
 		if podMetric.GetPod() != nil {
diff --git a/pkg/epp/scheduling/framework/plugins.go b/pkg/epp/scheduling/framework/plugins.go
index 2c22843..99397a4 100644
--- a/pkg/epp/scheduling/framework/plugins.go
+++ b/pkg/epp/scheduling/framework/plugins.go
@@ -28,7 +28,6 @@ const (
 	FilterExtensionPoint                 = "Filter"
 	ScorerExtensionPoint                 = "Scorer"
 	PickerExtensionPoint                 = "Picker"
-	PostCycleExtensionPoint              = "PostCycle"
 	ProcessProfilesResultsExtensionPoint = "ProcessProfilesResults"
 )
 
@@ -69,10 +68,3 @@ type Picker interface {
 	plugins.Plugin
 	Pick(ctx context.Context, cycleState *types.CycleState, scoredPods []*types.ScoredPod) *types.ProfileRunResult
 }
-
-// PostCycle is called by the scheduler after it selects a targetPod for the request in the SchedulerProfile cycle.
-// DEPRECATED - do not use PostCycle. this is in the process of deprecation.
-type PostCycle interface {
-	plugins.Plugin
-	PostCycle(ctx context.Context, cycleState *types.CycleState, res *types.ProfileRunResult)
-}
diff --git a/pkg/epp/scheduling/framework/plugins/multi/prefix/indexer.go b/pkg/epp/scheduling/framework/plugins/multi/prefix/indexer.go
index 0a209a8..bd9e2c9 100644
--- a/pkg/epp/scheduling/framework/plugins/multi/prefix/indexer.go
+++ b/pkg/epp/scheduling/framework/plugins/multi/prefix/indexer.go
@@ -38,15 +38,15 @@ type indexer struct {
 }
 
 // newIndexer initializes an indexer with size limits and starts cache size reporting.
-func newIndexer(maxLRUSize int) *indexer {
-	ix := &indexer{
+func newIndexer(ctx context.Context, maxLRUSize int) *indexer {
+	indexer := &indexer{
 		hashToPods: make(map[BlockHash]podSet),
 		podToLRU:   make(map[ServerID]*lru.Cache[BlockHash, struct{}]),
 		maxLRUSize: maxLRUSize,
 	}
 
-	go ix.ReportLRUSize(time.Second)
-	return ix
+	go indexer.reportLRUSize(ctx, time.Second)
+	return indexer
 }
 
 // Add adds a list of prefix hashes to the cache, tied to the server.
@@ -111,8 +111,8 @@ func (i *indexer) makeEvictionFn(pod ServerID) func(BlockHash, struct{}) {
 	}
 }
 
-// ReportLRUSize starts a goroutine that periodically reports the LRU cache size metric.
-func (i *indexer) ReportLRUSize(interval time.Duration) {
+// reportLRUSize starts a goroutine that periodically reports the LRU cache size metric.
+func (i *indexer) reportLRUSize(ctx context.Context, interval time.Duration) {
 	ticker := time.NewTicker(interval)
 	defer ticker.Stop()
 	for range ticker.C {
@@ -137,7 +137,7 @@ func (i *indexer) ReportLRUSize(interval time.Duration) {
 		}
 
 		metrics.RecordPrefixCacheSize(int64(totalEntries))
-		log.FromContext(context.TODO()).V(logutil.TRACE).Info("Prefix cache state",
+		log.FromContext(ctx).V(logutil.TRACE).Info("Prefix cache state",
 			"total entries", totalEntries,
 			"# pods", numPods,
 			"avg entries per pod", avg,
diff --git a/pkg/epp/scheduling/framework/plugins/multi/prefix/plugin.go b/pkg/epp/scheduling/framework/plugins/multi/prefix/plugin.go
index 9c1a8d8..2870288 100644
--- a/pkg/epp/scheduling/framework/plugins/multi/prefix/plugin.go
+++ b/pkg/epp/scheduling/framework/plugins/multi/prefix/plugin.go
@@ -21,6 +21,7 @@ import (
 	"encoding/binary"
 	"encoding/json"
 	"fmt"
+	"sync"
 
 	"github.com/cespare/xxhash/v2"
 	k8stypes "k8s.io/apimachinery/pkg/types"
@@ -28,6 +29,7 @@ import (
 
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/plugins"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/requestcontrol"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
 	logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
@@ -35,7 +37,7 @@ import (
 
 const (
 	// vLLM default token block size is 16, and a good guess of average characters per token is 4.
-	DefaultHashBlockSize = 64
+	DefaultBlockSize = 64
 	// The maximum number of blocks to match. Two long requests with the same prefix up to this
 	// limit will be indistinguishable.
 	// This parameter provides a trade-off between cache size, prefix matching speed and matching
@@ -56,15 +58,15 @@ const (
 )
 
 var DefaultConfig = Config{
-	HashBlockSize:          DefaultHashBlockSize,
+	BlockSize:              DefaultBlockSize,
 	MaxPrefixBlocksToMatch: DefaultMaxPrefixBlocks,
 	LRUCapacityPerServer:   DefaultLRUCapacityPerServer,
 }
 
 type Config struct {
-	// The input prompt is broken into sizes of HashBlockSize to calculate block hashes . Requests
+	// The input prompt is broken into sizes of BlockSize to calculate block hashes . Requests
 	// with length shorter than the block size will be ignored.
-	HashBlockSize int `json:"hashBlockSize"`
+	BlockSize int `json:"blockSize"`
 	// MaxPrefixBlocksToMatch is the maximum number of prefix blocks to match. Input beyond this limit will
 	// be ignored.
 	MaxPrefixBlocksToMatch int `json:"maxPrefixBlocksToMatch"`
@@ -73,9 +75,11 @@ type Config struct {
 }
 
 type Plugin struct {
-	Config
-	typedName plugins.TypedName
-	indexer   Indexer
+	typedName   plugins.TypedName
+	config      Config
+	pluginState *plugins.PluginState
+	indexer     Indexer
+	wg          sync.WaitGroup
 }
 
 // podSet holds an pods servers that may have a specific prefix hash.
@@ -121,13 +125,15 @@ func (s *SchedulingContextState) Clone() plugins.StateData {
 }
 
 // compile-time type assertion
-var _ framework.Scorer = &Plugin{}
-var _ framework.PostCycle = &Plugin{}
+var (
+	_ framework.Scorer          = &Plugin{}
+	_ requestcontrol.PreRequest = &Plugin{}
+)
 
 // PrefixCachePluginFactory defines the factory function for Prefix plugin.
-func PrefixCachePluginFactory(name string, rawParameters json.RawMessage, _ plugins.Handle) (plugins.Plugin, error) {
+func PrefixCachePluginFactory(name string, rawParameters json.RawMessage, handle plugins.Handle) (plugins.Plugin, error) {
 	parameters := Config{
-		HashBlockSize:          DefaultHashBlockSize,
+		BlockSize:              DefaultBlockSize,
 		MaxPrefixBlocksToMatch: DefaultMaxPrefixBlocks,
 		LRUCapacityPerServer:   DefaultLRUCapacityPerServer,
 	}
@@ -138,50 +144,51 @@ func PrefixCachePluginFactory(name string, rawParameters json.RawMessage, _ plug
 		}
 	}
 
-	return New(parameters).WithName(name), nil
+	return New(handle.Context(), parameters).WithName(name), nil
 }
 
 // New initializes a new prefix Plugin and returns its pointer.
-func New(config Config) *Plugin {
+func New(ctx context.Context, config Config) *Plugin {
 	capacity := config.LRUCapacityPerServer
 	if capacity <= 0 {
 		capacity = DefaultLRUCapacityPerServer
-		log.FromContext(context.TODO()).V(logutil.DEFAULT).Info(
+		log.FromContext(ctx).V(logutil.DEFAULT).Info(
 			"LRUCapacityPerServer is not positive, using default value",
 			"defaultCapacity", DefaultLRUCapacityPerServer,
 		)
 	}
 
 	return &Plugin{
-		typedName: plugins.TypedName{Type: PrefixCachePluginType, Name: PrefixCachePluginType},
-		Config:    config,
-		indexer:   newIndexer(capacity),
+		typedName:   plugins.TypedName{Type: PrefixCachePluginType, Name: PrefixCachePluginType},
+		config:      config,
+		pluginState: plugins.NewPluginState(ctx),
+		indexer:     newIndexer(ctx, capacity),
 	}
 }
 
 // TypedName returns the type and name tuple of this plugin instance.
-func (m *Plugin) TypedName() plugins.TypedName {
-	return m.typedName
+func (p *Plugin) TypedName() plugins.TypedName {
+	return p.typedName
 }
 
 // WithName sets the name of the plugin.
-func (m *Plugin) WithName(name string) *Plugin {
-	m.typedName.Name = name
-	return m
+func (p *Plugin) WithName(name string) *Plugin {
+	p.typedName.Name = name
+	return p
 }
 
 // Score returns the scoring result for the given list of pods based on context.
-func (m *Plugin) Score(ctx context.Context, cycleState *types.CycleState, request *types.LLMRequest, pods []types.Pod) map[types.Pod]float64 {
-	loggerTrace := log.FromContext(ctx).V(logutil.TRACE)
+func (p *Plugin) Score(ctx context.Context, cycleState *types.CycleState, request *types.LLMRequest, pods []types.Pod) map[types.Pod]float64 {
 	// pre score step, hashing prompt and find longest prefix match.
-	hashes := hashPrompt(ctx, request, m.HashBlockSize, m.MaxPrefixBlocksToMatch)
+	hashes := hashPrompt(ctx, request, p.config.BlockSize, p.config.MaxPrefixBlocksToMatch)
 	state := &SchedulingContextState{
 		PrefixHashes:       hashes,
-		PrefixCacheServers: m.matchLongestPrefix(ctx, hashes),
+		PrefixCacheServers: p.matchLongestPrefix(ctx, hashes),
 	}
 
-	cycleState.Write(plugins.StateKey(m.TypedName().Type), state)
-	loggerTrace.Info(fmt.Sprintf("cached servers: %+v", state.PrefixCacheServers), "hashes", state.PrefixHashes)
+	cycleState.Write(plugins.StateKey(p.TypedName().String()), state)
+	p.pluginState.Write(request.RequestId, plugins.StateKey(p.TypedName().String()), state)
+	log.FromContext(ctx).V(logutil.TRACE).Info("prefix cached state", "cached-servers", state.PrefixCacheServers, "hashes", state.PrefixHashes)
 	// calculate the scores of pods
 	scores := make(map[types.Pod]float64, len(pods))
 
@@ -200,31 +207,42 @@ func (m *Plugin) Score(ctx context.Context, cycleState *types.CycleState, reques
 	return scores
 }
 
-// PostCycle records in the plugin cache the result of the scheduling selection.
-func (m *Plugin) PostCycle(ctx context.Context, cycleState *types.CycleState, res *types.ProfileRunResult) {
-	targetPod := res.TargetPods[0].GetPod()
-	state, err := types.ReadCycleStateKey[*SchedulingContextState](cycleState, PrefixCachePluginType)
+// PreRequest records in the plugin cache the result of the scheduling selection.
+func (p *Plugin) PreRequest(ctx context.Context, request *types.LLMRequest, schedulingResult *types.SchedulingResult, _ int) {
+	primaryProfileResult := schedulingResult.ProfileResults[schedulingResult.PrimaryProfileName]
+	targetPod := primaryProfileResult.TargetPods[0].GetPod() // get the first pod of the primary profile
+
+	state, err := plugins.ReadPluginStateKey[*SchedulingContextState](p.pluginState, request.RequestId, plugins.StateKey(p.TypedName().String()))
+	p.pluginState.Delete(request.RequestId) // delete the state explicitly after completing using it
 	if err != nil {
-		log.FromContext(ctx).Error(err, "failed to read prefix plugin cycle state")
+		log.FromContext(ctx).Error(err, "failed to read prefix plugin state", "requestID", request.RequestId)
 		return
 	}
 
-	m.indexer.Add(state.PrefixHashes, ServerID(targetPod.NamespacedName))
+	// This function is just adding data, it does not need to block other operations.
+	// TODO: look into making this entire function async, none of this needs to be done in-band
+	// The PR that introduces this change is meant as a cherrypick, so it was minimally invasive.
+	// WaitGroup is added to the Plugin struct to allow waiting in tests.
+	p.wg.Add(1)
+	go func() {
+		p.indexer.Add(state.PrefixHashes, ServerID(targetPod.NamespacedName))
+		p.wg.Done()
+	}()
 
 	total := len(state.PrefixHashes)
 	matchLen := state.PrefixCacheServers[ServerID(targetPod.NamespacedName)]
-	metrics.RecordPrefixCacheMatch(matchLen*m.HashBlockSize, total*m.HashBlockSize)
+	metrics.RecordPrefixCacheMatch(matchLen*p.config.BlockSize, total*p.config.BlockSize)
 }
 
 // matchLongestPrefix returns a map of servers and length of prefix that each server caches.
-func (m *Plugin) matchLongestPrefix(ctx context.Context, hashes []BlockHash) map[ServerID]int {
+func (p *Plugin) matchLongestPrefix(ctx context.Context, hashes []BlockHash) map[ServerID]int {
 	loggerTrace := log.FromContext(ctx).V(logutil.TRACE)
 	res := make(map[ServerID]int)
 	// Use a greedy strategy to search from the longest prefix.
 	// NOTE: It's possible to further optimize this with a binary search.
 	for i := 0; i < len(hashes); i++ {
 		hash := hashes[i]
-		cachedServers := m.indexer.Get(hash)
+		cachedServers := p.indexer.Get(hash)
 		if len(cachedServers) == 0 {
 			break
 		} else {
@@ -232,7 +250,6 @@ func (m *Plugin) matchLongestPrefix(ctx context.Context, hashes []BlockHash) map
 			for server := range cachedServers {
 				// Update servers with their longest prefix match.
 				res[server]++
-
 			}
 		}
 	}
@@ -240,29 +257,47 @@ func (m *Plugin) matchLongestPrefix(ctx context.Context, hashes []BlockHash) map
 }
 
 // hashPrompt divides the prompt into blocks and calculate the prefix cache for each block.
-// hash(0) is the hash of the model name, since different models generally don't share prefix cache.
+// hash[0] is calculated including the model name and cache_salt(if provided), since different models generally don't share prefix cache.
 // For block i, hash(i) = hash(block i content, hash(i-1)).
 func hashPrompt(ctx context.Context, request *types.LLMRequest, cacheBlockSize int, maxPrefixBlocks int) []BlockHash {
 	loggerDebug := log.FromContext(ctx).V(logutil.DEBUG)
-	prompt := []byte(request.Prompt)
-	if len(prompt) < cacheBlockSize {
-		loggerDebug.Info("Request body too small for prefix cache", "size", len(prompt), "block size", cacheBlockSize)
+	if request == nil || request.Body == nil {
+		loggerDebug.Info("Request or request data is nil, skipping hashing")
+		return nil
+	}
+
+	userInput, err := getUserInputBytes(request)
+	if err != nil {
+		loggerDebug.Error(err, "Failed to get user input bytes")
+		return nil
+	}
+
+	if len(userInput) < cacheBlockSize {
+		loggerDebug.Info("Request body too small for prefix cache", "size", len(userInput), "block size", cacheBlockSize)
 		return nil
 	}
-	if len(prompt) > cacheBlockSize*maxPrefixBlocks {
-		loggerDebug.Info("Truncating input", "size", len(prompt), "max prefix blocks", maxPrefixBlocks, "block size", cacheBlockSize)
-		prompt = prompt[:maxPrefixBlocks*cacheBlockSize]
+	if len(userInput) > cacheBlockSize*maxPrefixBlocks {
+		loggerDebug.Info("Truncating input", "size", len(userInput), "max prefix blocks", maxPrefixBlocks, "block size", cacheBlockSize)
+		userInput = userInput[:maxPrefixBlocks*cacheBlockSize]
 	}
-	// Split the body into blocks of size cacheBlockSize. The +1 is to account for the model.
+	// Split the body into blocks of size cacheBlockSize.
 	// If the last block is smaller than cacheBlockSize, it will be ignored.
-	res := make([]BlockHash, 0, 1+len(prompt)/cacheBlockSize)
+	res := make([]BlockHash, 0, len(userInput)/cacheBlockSize)
 	// Add the model to the first block hash so that different models have different hashes even with the same body.
-	res = append(res, BlockHash(xxhash.Sum64String(request.TargetModel)))
-	for i := 0; i+cacheBlockSize <= len(prompt); i += cacheBlockSize {
-		block := prompt[i : i+cacheBlockSize]
-		prevBlockHash := res[len(res)-1]
-		block = append(block, toBytes(prevBlockHash)...)
-		res = append(res, BlockHash(xxhash.Sum64(block)))
+	h := xxhash.New()
+	_, _ = h.Write([]byte(request.TargetModel))
+	if cacheSalt := request.Body.CacheSalt(); cacheSalt != "" {
+		_, _ = h.Write([]byte(cacheSalt))
+	}
+
+	prevBlockHash := BlockHash(h.Sum64())
+	for i := 0; i+cacheBlockSize <= len(userInput); i += cacheBlockSize {
+		h.Reset()
+		_, _ = h.Write(userInput[i : i+cacheBlockSize])
+		_, _ = h.Write(toBytes(prevBlockHash))
+		res = append(res, BlockHash(h.Sum64()))
+
+		prevBlockHash = res[len(res)-1]
 	}
 	return res
 }
@@ -272,3 +307,12 @@ func toBytes(i BlockHash) []byte {
 	binary.LittleEndian.PutUint64(bytes, uint64(i))
 	return bytes
 }
+
+func getUserInputBytes(request *types.LLMRequest) ([]byte, error) {
+	if request.Body.Completions != nil { // assumed to be valid if not nil
+		return []byte(request.Body.Completions.Prompt), nil
+	}
+
+	// must be chat-completions request at this point, return bytes of entire messages
+	return json.Marshal(request.Body.ChatCompletions.Messages)
+}
diff --git a/pkg/epp/scheduling/framework/plugins/picker/common.go b/pkg/epp/scheduling/framework/plugins/picker/common.go
index 4bbc300..c865584 100644
--- a/pkg/epp/scheduling/framework/plugins/picker/common.go
+++ b/pkg/epp/scheduling/framework/plugins/picker/common.go
@@ -16,6 +16,13 @@ limitations under the License.
 
 package picker
 
+import (
+	"math/rand/v2"
+	"time"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
+)
+
 const (
 	DefaultMaxNumOfEndpoints = 1 // common default to all pickers
 )
@@ -24,3 +31,14 @@ const (
 type pickerParameters struct {
 	MaxNumOfEndpoints int `json:"maxNumOfEndpoints"`
 }
+
+func shuffleScoredPods(scoredPods []*types.ScoredPod) {
+	// Rand package is not safe for concurrent use, so we create a new instance.
+	// Source: https://pkg.go.dev/math/rand/v2#pkg-overview
+	randomGenerator := rand.New(rand.NewPCG(uint64(time.Now().UnixNano()), 0))
+
+	// Shuffle in-place
+	randomGenerator.Shuffle(len(scoredPods), func(i, j int) {
+		scoredPods[i], scoredPods[j] = scoredPods[j], scoredPods[i]
+	})
+}
diff --git a/pkg/epp/scheduling/framework/plugins/picker/max_score_picker.go b/pkg/epp/scheduling/framework/plugins/picker/max_score_picker.go
index a0e973f..33e99bd 100644
--- a/pkg/epp/scheduling/framework/plugins/picker/max_score_picker.go
+++ b/pkg/epp/scheduling/framework/plugins/picker/max_score_picker.go
@@ -20,9 +20,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"math/rand"
 	"slices"
-	"time"
 
 	"sigs.k8s.io/controller-runtime/pkg/log"
 
@@ -82,18 +80,11 @@ func (p *MaxScorePicker) TypedName() plugins.TypedName {
 
 // Pick selects the pod with the maximum score from the list of candidates.
 func (p *MaxScorePicker) Pick(ctx context.Context, cycleState *types.CycleState, scoredPods []*types.ScoredPod) *types.ProfileRunResult {
-	log.FromContext(ctx).V(logutil.DEBUG).Info(fmt.Sprintf("Selecting maximum '%d' pods from %d candidates sorted by max score: %+v", p.maxNumOfEndpoints,
-		len(scoredPods), scoredPods))
-
-	// TODO: merge this with the logic in RandomPicker
-	// Rand package is not safe for concurrent use, so we create a new instance.
-	// Source: https://pkg.go.dev/math/rand#pkg-overview
-	randomGenerator := rand.New(rand.NewSource(time.Now().UnixNano()))
+	log.FromContext(ctx).V(logutil.DEBUG).Info("Selecting pods from candidates sorted by max score", "max-num-of-endpoints", p.maxNumOfEndpoints,
+		"num-of-candidates", len(scoredPods), "scored-pods", scoredPods)
 
 	// Shuffle in-place - needed for random tie break when scores are equal
-	randomGenerator.Shuffle(len(scoredPods), func(i, j int) {
-		scoredPods[i], scoredPods[j] = scoredPods[j], scoredPods[i]
-	})
+	shuffleScoredPods(scoredPods)
 
 	slices.SortStableFunc(scoredPods, func(i, j *types.ScoredPod) int { // highest score first
 		if i.Score > j.Score {
diff --git a/pkg/epp/scheduling/framework/plugins/picker/random_picker.go b/pkg/epp/scheduling/framework/plugins/picker/random_picker.go
index b571ce3..10ad684 100644
--- a/pkg/epp/scheduling/framework/plugins/picker/random_picker.go
+++ b/pkg/epp/scheduling/framework/plugins/picker/random_picker.go
@@ -20,8 +20,6 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"math/rand"
-	"time"
 
 	"sigs.k8s.io/controller-runtime/pkg/log"
 
@@ -38,6 +36,7 @@ const (
 // compile-time type validation
 var _ framework.Picker = &RandomPicker{}
 
+// RandomPickerFactory defines the factory function for RandomPicker.
 func RandomPickerFactory(name string, rawParameters json.RawMessage, _ plugins.Handle) (plugins.Plugin, error) {
 	parameters := pickerParameters{MaxNumOfEndpoints: DefaultMaxNumOfEndpoints}
 	if rawParameters != nil {
@@ -80,18 +79,11 @@ func (p *RandomPicker) TypedName() plugins.TypedName {
 
 // Pick selects random pod(s) from the list of candidates.
 func (p *RandomPicker) Pick(ctx context.Context, _ *types.CycleState, scoredPods []*types.ScoredPod) *types.ProfileRunResult {
-	log.FromContext(ctx).V(logutil.DEBUG).Info(fmt.Sprintf("Selecting maximum '%d' pods from %d candidates randomly: %+v", p.maxNumOfEndpoints,
-		len(scoredPods), scoredPods))
-
-	// TODO: merge this with the logic in MaxScorePicker
-	// Rand package is not safe for concurrent use, so we create a new instance.
-	// Source: https://pkg.go.dev/math/rand#pkg-overview
-	randomGenerator := rand.New(rand.NewSource(time.Now().UnixNano()))
+	log.FromContext(ctx).V(logutil.DEBUG).Info("Selecting pods from candidates randomly", "max-num-of-endpoints", p.maxNumOfEndpoints,
+		"num-of-candidates", len(scoredPods), "scored-pods", scoredPods)
 
 	// Shuffle in-place
-	randomGenerator.Shuffle(len(scoredPods), func(i, j int) {
-		scoredPods[i], scoredPods[j] = scoredPods[j], scoredPods[i]
-	})
+	shuffleScoredPods(scoredPods)
 
 	// if we have enough pods to return keep only the relevant subset
 	if p.maxNumOfEndpoints < len(scoredPods) {
diff --git a/pkg/epp/scheduling/framework/plugins/picker/weighted_random_picker.go b/pkg/epp/scheduling/framework/plugins/picker/weighted_random_picker.go
new file mode 100644
index 0000000..540ede4
--- /dev/null
+++ b/pkg/epp/scheduling/framework/plugins/picker/weighted_random_picker.go
@@ -0,0 +1,153 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package picker
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"math"
+	"math/rand"
+	"slices"
+	"sort"
+	"time"
+
+	"sigs.k8s.io/controller-runtime/pkg/log"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/plugins"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
+	logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
+)
+
+const (
+	WeightedRandomPickerType = "weighted-random-picker"
+)
+
+// weightedScoredPod represents a scored pod with its A-Res sampling key
+type weightedScoredPod struct {
+	*types.ScoredPod
+	key float64
+}
+
+// compile-time type validation
+var _ framework.Picker = &WeightedRandomPicker{}
+
+// WeightedRandomPickerFactory defines the factory function for WeightedRandomPicker.
+func WeightedRandomPickerFactory(name string, rawParameters json.RawMessage, _ plugins.Handle) (plugins.Plugin, error) {
+	parameters := pickerParameters{MaxNumOfEndpoints: DefaultMaxNumOfEndpoints}
+	if rawParameters != nil {
+		if err := json.Unmarshal(rawParameters, &parameters); err != nil {
+			return nil, fmt.Errorf("failed to parse the parameters of the '%s' picker - %w", WeightedRandomPickerType, err)
+		}
+	}
+
+	return NewWeightedRandomPicker(parameters.MaxNumOfEndpoints).WithName(name), nil
+}
+
+// NewWeightedRandomPicker initializes a new WeightedRandomPicker and returns its pointer.
+func NewWeightedRandomPicker(maxNumOfEndpoints int) *WeightedRandomPicker {
+	if maxNumOfEndpoints <= 0 {
+		maxNumOfEndpoints = DefaultMaxNumOfEndpoints // on invalid configuration value, fallback to default value
+	}
+
+	return &WeightedRandomPicker{
+		typedName:         plugins.TypedName{Type: WeightedRandomPickerType, Name: WeightedRandomPickerType},
+		maxNumOfEndpoints: maxNumOfEndpoints,
+		randomPicker:      NewRandomPicker(maxNumOfEndpoints),
+	}
+}
+
+// WeightedRandomPicker picks pod(s) from the list of candidates based on weighted random sampling using A-Res algorithm.
+// Reference: https://utopia.duth.gr/~pefraimi/research/data/2007EncOfAlg.pdf.
+//
+// The picker at its core is picking pods randomly, where the probability of the pod to get picked is derived
+// from its weighted score.
+// Algorithm:
+// - Uses A-Res (Algorithm for Reservoir Sampling): keyᵢ = Uᵢ^(1/wᵢ)
+// - Selects k items with largest keys for mathematically correct weighted sampling
+// - More efficient than traditional cumulative probability approach
+//
+// Key characteristics:
+// - Mathematically correct weighted random sampling
+// - Single pass algorithm with O(n + k log k) complexity
+type WeightedRandomPicker struct {
+	typedName         plugins.TypedName
+	maxNumOfEndpoints int
+	randomPicker      *RandomPicker // fallback for zero weights
+}
+
+// WithName sets the name of the picker.
+func (p *WeightedRandomPicker) WithName(name string) *WeightedRandomPicker {
+	p.typedName.Name = name
+	return p
+}
+
+// TypedName returns the type and name tuple of this plugin instance.
+func (p *WeightedRandomPicker) TypedName() plugins.TypedName {
+	return p.typedName
+}
+
+// Pick selects the pod(s) randomly from the list of candidates, where the probability of the pod to get picked is derived
+// from its weighted score.
+func (p *WeightedRandomPicker) Pick(ctx context.Context, cycleState *types.CycleState, scoredPods []*types.ScoredPod) *types.ProfileRunResult {
+	// Check if there is at least one pod with Score > 0, if not let random picker run
+	if slices.IndexFunc(scoredPods, func(scoredPod *types.ScoredPod) bool { return scoredPod.Score > 0 }) == -1 {
+		log.FromContext(ctx).V(logutil.DEBUG).Info("All scores are zero, delegating to RandomPicker for uniform selection")
+		return p.randomPicker.Pick(ctx, cycleState, scoredPods)
+	}
+
+	log.FromContext(ctx).V(logutil.DEBUG).Info("Selecting pods from candidates by random weighted picker", "max-num-of-endpoints", p.maxNumOfEndpoints,
+		"num-of-candidates", len(scoredPods), "scored-pods", scoredPods)
+
+	randomGenerator := rand.New(rand.NewSource(time.Now().UnixNano()))
+
+	// A-Res algorithm: keyᵢ = Uᵢ^(1/wᵢ)
+	weightedPods := make([]weightedScoredPod, len(scoredPods))
+
+	for i, scoredPod := range scoredPods {
+		// Handle zero score
+		if scoredPod.Score <= 0 {
+			// Assign key=0 for zero-score pods (effectively excludes them from selection)
+			weightedPods[i] = weightedScoredPod{ScoredPod: scoredPod, key: 0}
+			continue
+		}
+
+		// If we're here the scoredPod.Score > 0. Generate a random number U in (0,1)
+		u := randomGenerator.Float64()
+		if u == 0 {
+			u = 1e-10 // Avoid log(0)
+		}
+
+		weightedPods[i] = weightedScoredPod{ScoredPod: scoredPod, key: math.Pow(u, 1.0/scoredPod.Score)} // key = U^(1/weight)
+	}
+
+	// Sort by key in descending order (largest keys first)
+	sort.Slice(weightedPods, func(i, j int) bool {
+		return weightedPods[i].key > weightedPods[j].key
+	})
+
+	// Select top k pods
+	selectedCount := min(p.maxNumOfEndpoints, len(weightedPods))
+
+	targetPods := make([]types.Pod, selectedCount)
+	for i := range selectedCount {
+		targetPods[i] = weightedPods[i].ScoredPod
+	}
+
+	return &types.ProfileRunResult{TargetPods: targetPods}
+}
diff --git a/pkg/epp/scheduling/framework/scheduler_profile.go b/pkg/epp/scheduling/framework/scheduler_profile.go
index b3b24d5..9c0ae0a 100644
--- a/pkg/epp/scheduling/framework/scheduler_profile.go
+++ b/pkg/epp/scheduling/framework/scheduler_profile.go
@@ -34,19 +34,17 @@ import (
 // NewSchedulerProfile creates a new SchedulerProfile object and returns its pointer.
 func NewSchedulerProfile() *SchedulerProfile {
 	return &SchedulerProfile{
-		filters:          []Filter{},
-		scorers:          []*WeightedScorer{},
-		postCyclePlugins: []PostCycle{},
+		filters: []Filter{},
+		scorers: []*WeightedScorer{},
 		// picker remains nil since profile doesn't support multiple pickers
 	}
 }
 
 // SchedulerProfile provides a profile configuration for the scheduler which influence routing decisions.
 type SchedulerProfile struct {
-	filters          []Filter
-	scorers          []*WeightedScorer
-	picker           Picker
-	postCyclePlugins []PostCycle
+	filters []Filter
+	scorers []*WeightedScorer
+	picker  Picker
 }
 
 // WithFilters sets the given filter plugins as the Filter plugins.
@@ -70,13 +68,6 @@ func (p *SchedulerProfile) WithPicker(picker Picker) *SchedulerProfile {
 	return p
 }
 
-// WithPostCyclePlugins sets the given plugins as the PostCycle plugins.
-// If the SchedulerProfile has PostCycle plugins, this call replaces the existing plugins with the given ones.
-func (p *SchedulerProfile) WithPostCyclePlugins(plugins ...PostCycle) *SchedulerProfile {
-	p.postCyclePlugins = plugins
-	return p
-}
-
 // AddPlugins adds the given plugins to all scheduler plugins according to the interfaces each plugin implements.
 // A plugin may implement more than one scheduler plugin interface.
 // Special Case: In order to add a scorer, one must use the scorer.NewWeightedScorer function in order to provide a weight.
@@ -99,9 +90,6 @@ func (p *SchedulerProfile) AddPlugins(pluginObjects ...plugins.Plugin) error {
 			}
 			p.picker = picker
 		}
-		if postCyclePlugin, ok := plugin.(PostCycle); ok {
-			p.postCyclePlugins = append(p.postCyclePlugins, postCyclePlugin)
-		}
 	}
 	return nil
 }
@@ -115,21 +103,17 @@ func (p *SchedulerProfile) String() string {
 	for i, scorer := range p.scorers {
 		scorerNames[i] = fmt.Sprintf("%s: %d", scorer.TypedName(), scorer.Weight())
 	}
-	postCyclePluginNames := make([]string, len(p.postCyclePlugins))
-	for i, postCyclePlugin := range p.postCyclePlugins {
-		postCyclePluginNames[i] = postCyclePlugin.TypedName().String()
-	}
+
 	return fmt.Sprintf(
-		"{Filters: [%s], Scorers: [%s], Picker: %s, PostCyclePlugins: [%s]}",
+		"{Filters: [%s], Scorers: [%s], Picker: %s}",
 		strings.Join(filterNames, ", "),
 		strings.Join(scorerNames, ", "),
 		p.picker.TypedName(),
-		strings.Join(postCyclePluginNames, ", "),
 	)
 }
 
-// RunCycle runs a SchedulerProfile cycle. In other words, it invokes all the SchedulerProfile plugins in this
-// order - Filters, Scorers, Picker, PostCyclePlugins. After completing all, it returns the result.
+// Run runs a SchedulerProfile. It invokes all the SchedulerProfile plugins for the given request in this
+// order - Filters, Scorers, Picker. After completing all, it returns the result.
 func (p *SchedulerProfile) Run(ctx context.Context, request *types.LLMRequest, cycleState *types.CycleState, candidatePods []types.Pod) (*types.ProfileRunResult, error) {
 	pods := p.runFilterPlugins(ctx, request, cycleState, candidatePods)
 	if len(pods) == 0 {
@@ -140,8 +124,6 @@ func (p *SchedulerProfile) Run(ctx context.Context, request *types.LLMRequest, c
 
 	result := p.runPickerPlugin(ctx, cycleState, weightedScorePerPod)
 
-	p.runPostCyclePlugins(ctx, cycleState, result)
-
 	return result, nil
 }
 
@@ -166,8 +148,8 @@ func (p *SchedulerProfile) runFilterPlugins(ctx context.Context, request *types.
 }
 
 func (p *SchedulerProfile) runScorerPlugins(ctx context.Context, request *types.LLMRequest, cycleState *types.CycleState, pods []types.Pod) map[types.Pod]float64 {
-	loggerDebug := log.FromContext(ctx).V(logutil.DEBUG)
-	loggerDebug.Info("Before running scorer plugins", "pods", pods)
+	logger := log.FromContext(ctx)
+	logger.V(logutil.DEBUG).Info("Before running scorer plugins", "pods", pods)
 
 	weightedScorePerPod := make(map[types.Pod]float64, len(pods))
 	for _, pod := range pods {
@@ -175,16 +157,17 @@ func (p *SchedulerProfile) runScorerPlugins(ctx context.Context, request *types.
 	}
 	// Iterate through each scorer in the chain and accumulate the weighted scores.
 	for _, scorer := range p.scorers {
-		loggerDebug.Info("Running scorer plugin", "plugin", scorer.TypedName())
+		logger.V(logutil.DEBUG).Info("Running scorer plugin", "plugin", scorer.TypedName())
 		before := time.Now()
 		scores := scorer.Score(ctx, cycleState, request, pods)
 		metrics.RecordPluginProcessingLatency(ScorerExtensionPoint, scorer.TypedName().Type, scorer.TypedName().Name, time.Since(before))
 		for pod, score := range scores { // weight is relative to the sum of weights
+			logger.V(logutil.DEBUG).Info("Calculated score", "plugin", scorer.TypedName(), "endpoint", pod.GetPod().NamespacedName, "score", score)
 			weightedScorePerPod[pod] += enforceScoreRange(score) * float64(scorer.Weight())
 		}
-		loggerDebug.Info("Completed running scorer plugin successfully", "plugin", scorer.TypedName())
+		logger.V(logutil.DEBUG).Info("Completed running scorer plugin successfully", "plugin", scorer.TypedName())
 	}
-	loggerDebug.Info("Completed running scorer plugins successfully")
+	logger.V(logutil.DEBUG).Info("Completed running scorer plugins successfully")
 
 	return weightedScorePerPod
 }
@@ -198,7 +181,7 @@ func (p *SchedulerProfile) runPickerPlugin(ctx context.Context, cycleState *type
 		i++
 	}
 
-	loggerDebug.Info("Running picker plugin", "plugin", p.picker.TypedName(), "pods-weighted-score", fmt.Sprint(weightedScorePerPod))
+	loggerDebug.Info("Running picker plugin", "plugin", p.picker.TypedName(), "pods-weighted-score", weightedScorePerPod)
 	before := time.Now()
 	result := p.picker.Pick(ctx, cycleState, scoredPods)
 	metrics.RecordPluginProcessingLatency(PickerExtensionPoint, p.picker.TypedName().Type, p.picker.TypedName().Name, time.Since(before))
@@ -207,17 +190,6 @@ func (p *SchedulerProfile) runPickerPlugin(ctx context.Context, cycleState *type
 	return result
 }
 
-func (p *SchedulerProfile) runPostCyclePlugins(ctx context.Context, cycleState *types.CycleState, result *types.ProfileRunResult) {
-	loggerDebug := log.FromContext(ctx).V(logutil.DEBUG)
-	for _, plugin := range p.postCyclePlugins {
-		loggerDebug.Info("Running post-cycle plugin", "plugin", plugin.TypedName())
-		before := time.Now()
-		plugin.PostCycle(ctx, cycleState, result)
-		metrics.RecordPluginProcessingLatency(PostCycleExtensionPoint, plugin.TypedName().Type, plugin.TypedName().Name, time.Since(before))
-		loggerDebug.Info("Completed running post-cycle plugin successfully", "plugin", plugin.TypedName())
-	}
-}
-
 func enforceScoreRange(score float64) float64 {
 	if score < 0 {
 		return 0
diff --git a/pkg/epp/scheduling/types/types.go b/pkg/epp/scheduling/types/types.go
index 2962117..c93f0c5 100644
--- a/pkg/epp/scheduling/types/types.go
+++ b/pkg/epp/scheduling/types/types.go
@@ -23,20 +23,106 @@ import (
 	backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 )
 
+const nilString = "<nil>"
+
 // LLMRequest is a structured representation of the fields we parse out of the LLMRequest body.
 type LLMRequest struct {
 	// RequestId is the Envoy generated Id for the request being processed
 	RequestId string
 	// TargetModel is the final target model after traffic split.
 	TargetModel string
-	// Prompt is the prompt that was sent in the request body.
-	Prompt string
+	// Data contains the request-body fields that we parse out as user input.
+	Body *LLMRequestBody
 	// Headers is a map of the request headers.
 	Headers map[string]string
 }
 
 func (r *LLMRequest) String() string {
-	return fmt.Sprintf("RequestID: %s, TargetModel: %s, PromptLength: %d, Headers: %v", r.RequestId, r.TargetModel, len(r.Prompt), r.Headers)
+	if r == nil {
+		return nilString
+	}
+
+	return fmt.Sprintf("RequestID: %s, TargetModel: %s, Body: %s, Headers: %v",
+		r.RequestId, r.TargetModel, r.Body, r.Headers)
+}
+
+// LLMRequestBody contains the request-body fields that we parse out as user input,
+// to be used in forming scheduling decisions.
+// An LLMRequestBody must contain exactly one of CompletionsRequest or ChatCompletionsRequest.
+type LLMRequestBody struct {
+	// CompletionsRequest is the representation of the OpenAI /v1/completions request body.
+	Completions *CompletionsRequest `json:"completions,omitempty"`
+	// ChatCompletionsRequest is the representation of the OpenAI /v1/chat_completions request body.
+	ChatCompletions *ChatCompletionsRequest `json:"chat_completions,omitempty"`
+}
+
+func (r *LLMRequestBody) CacheSalt() string {
+	if r.ChatCompletions == nil && r.Completions == nil {
+		return ""
+	}
+
+	if r.ChatCompletions != nil {
+		return r.ChatCompletions.CacheSalt
+	}
+
+	return r.Completions.CacheSalt
+}
+
+// CompletionsRequest is a structured representation of the fields we parse out of the
+// /v1/completions request body.
+// This struct includes fields usable for plugins and scheduling decisions - and not the entire
+// API spec.
+type CompletionsRequest struct {
+	// Prompt is the prompt that was sent in the request body.
+	Prompt string `json:"prompt,omitempty"`
+	// CacheSalt is an optional request parameter to isolate prefix caches for security reasons.
+	CacheSalt string `json:"cache_salt,omitempty"`
+}
+
+func (r *CompletionsRequest) String() string {
+	if r == nil {
+		return nilString
+	}
+
+	return fmt.Sprintf("{PromptLength: %d}", len(r.Prompt))
+}
+
+// ChatCompletionsRequest is a structured representation of the fields we parse out of the
+// /v1/chat/completions request body.
+// This struct includes fields usable for plugins and scheduling decisions - and not the entire
+// API spec.
+type ChatCompletionsRequest struct {
+	/* parameters from the official OpenAI chat-completions API */
+	Messages []Message     `json:"messages,omitempty"`
+	Tools    []interface{} `json:"tools,omitempty"`
+	/* parameters from the HuggingFace transformers chat-templates API */
+	Documents                 []interface{}          `json:"documents,omitempty"`
+	ChatTemplate              string                 `json:"chat_template,omitempty"`
+	ReturnAssistantTokensMask bool                   `json:"return_assistant_tokens_mask,omitempty"`
+	ContinueFinalMessage      bool                   `json:"continue_final_message,omitempty"`
+	AddGenerationPrompt       bool                   `json:"add_generation_prompt,omitempty"`
+	ChatTemplateKWArgs        map[string]interface{} `json:"chat_template_kwargs,omitempty"`
+	// CacheSalt is an optional request parameter to isolate prefix caches for security reasons.
+	CacheSalt string `json:"cache_salt,omitempty"`
+}
+
+func (r *ChatCompletionsRequest) String() string {
+	if r == nil {
+		return nilString
+	}
+
+	messagesLen := 0
+	for _, msg := range r.Messages {
+		messagesLen += len(msg.Content)
+	}
+
+	return fmt.Sprintf("{MessagesLength: %d}", messagesLen)
+}
+
+// Message represents a single message in a chat-completions request.
+type Message struct {
+	Role    string
+	Content string // TODO: support multi-modal content
 }
 
 type Pod interface {
@@ -52,8 +138,9 @@ type ScoredPod struct {
 
 func (pm *PodMetrics) String() string {
 	if pm == nil {
-		return ""
+		return nilString
 	}
+
 	return fmt.Sprintf("%+v", *pm)
 }
 
diff --git a/pkg/epp/server/runserver.go b/pkg/epp/server/runserver.go
index 1b84bd7..870acc7 100644
--- a/pkg/epp/server/runserver.go
+++ b/pkg/epp/server/runserver.go
@@ -38,6 +38,7 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/common"
 	backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/controller"
+	dlmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datalayer/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datastore"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/handlers"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/requestcontrol"
@@ -56,6 +57,7 @@ type ExtProcServerRunner struct {
 	MetricsStalenessThreshold        time.Duration
 	Director                         *requestcontrol.Director
 	SaturationDetector               requestcontrol.SaturationDetector
+	UseExperimentalDatalayerV2       bool // Pluggable data layer feature flag
 
 	// This should only be used in tests. We won't need this once we do not inject metrics in the tests.
 	// TODO:(https://github.com/kubernetes-sigs/gateway-api-inference-extension/issues/432) Cleanup
@@ -138,7 +140,12 @@ func (r *ExtProcServerRunner) SetupWithManager(ctx context.Context, mgr ctrl.Man
 // The runnable implements LeaderElectionRunnable with leader election disabled.
 func (r *ExtProcServerRunner) AsRunnable(logger logr.Logger) manager.Runnable {
 	return runnable.NoLeaderElection(manager.RunnableFunc(func(ctx context.Context) error {
-		backendmetrics.StartMetricsLogger(ctx, r.Datastore, r.RefreshPrometheusMetricsInterval, r.MetricsStalenessThreshold)
+		if r.UseExperimentalDatalayerV2 {
+			dlmetrics.StartMetricsLogger(ctx, r.Datastore, r.RefreshPrometheusMetricsInterval, r.MetricsStalenessThreshold)
+		} else {
+			backendmetrics.StartMetricsLogger(ctx, r.Datastore, r.RefreshPrometheusMetricsInterval, r.MetricsStalenessThreshold)
+		}
+
 		var srv *grpc.Server
 		if r.SecureServing {
 			var cert tls.Certificate
@@ -150,8 +157,7 @@ func (r *ExtProcServerRunner) AsRunnable(logger logr.Logger) manager.Runnable {
 				cert, err = tlsutil.CreateSelfSignedTLSCertificate(logger)
 			}
 			if err != nil {
-				logger.Error(err, "Failed to create self signed certificate")
-				return err
+				return fmt.Errorf("failed to create self signed certificate - %w", err)
 			}
 
 			creds := credentials.NewTLS(&tls.Config{
diff --git a/pkg/epp/util/request/body.go b/pkg/epp/util/request/body.go
index 46de1fa..0787741 100644
--- a/pkg/epp/util/request/body.go
+++ b/pkg/epp/util/request/body.go
@@ -17,70 +17,43 @@ limitations under the License.
 package request
 
 import (
-	"fmt"
+	"encoding/json"
 
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
 	errutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/error"
 )
 
-func ExtractPromptFromRequestBody(body map[string]any) (string, error) {
-	if _, ok := body["messages"]; ok {
-		return extractPromptFromMessagesField(body)
+// ExtractRequestBody extracts the LLMRequestBody from the given request body map.
+func ExtractRequestBody(rawBody map[string]any) (*types.LLMRequestBody, error) {
+	// Convert map back to JSON bytes
+	jsonBytes, err := json.Marshal(rawBody)
+	if err != nil {
+		return nil, errutil.Error{Code: errutil.BadRequest, Msg: "invalid request body"}
 	}
-	return extractPromptField(body)
-}
 
-func extractPromptField(body map[string]any) (string, error) {
-	prompt, ok := body["prompt"]
-	if !ok {
-		return "", errutil.Error{Code: errutil.BadRequest, Msg: "prompt not found in request"}
-	}
-	promptStr, ok := prompt.(string)
-	if !ok {
-		return "", errutil.Error{Code: errutil.BadRequest, Msg: "prompt is not a string"}
+	// Try completions request first
+	var completions types.CompletionsRequest
+	if err = json.Unmarshal(jsonBytes, &completions); err == nil && completions.Prompt != "" {
+		return &types.LLMRequestBody{Completions: &completions}, nil
 	}
-	return promptStr, nil
-}
 
-func extractPromptFromMessagesField(body map[string]any) (string, error) {
-	messages, ok := body["messages"]
-	if !ok {
-		return "", errutil.Error{Code: errutil.BadRequest, Msg: "messages not found in request"}
-	}
-	messageList, ok := messages.([]any)
-	if !ok {
-		return "", errutil.Error{Code: errutil.BadRequest, Msg: "messages is not a list"}
-	}
-	if len(messageList) == 0 {
-		return "", errutil.Error{Code: errutil.BadRequest, Msg: "messages is empty"}
+	// Try chat completions
+	var chatCompletions types.ChatCompletionsRequest
+	if err = json.Unmarshal(jsonBytes, &chatCompletions); err != nil {
+		return nil, errutil.Error{Code: errutil.BadRequest, Msg: "invalid request format"}
 	}
 
-	prompt := ""
-	for _, msg := range messageList {
-		msgMap, ok := msg.(map[string]any)
-		if !ok {
-			continue
-		}
-		content, ok := msgMap["content"]
-		if !ok {
-			continue
-		}
-		contentStr, ok := content.(string)
-		if !ok {
-			continue
-		}
-		role, ok := msgMap["role"]
-		if !ok {
-			continue
-		}
-		roleStr, ok := role.(string)
-		if !ok {
-			continue
-		}
-		prompt += constructChatMessage(roleStr, contentStr)
+	if err = validateChatCompletionsMessages(chatCompletions.Messages); err != nil {
+		return nil, errutil.Error{Code: errutil.BadRequest, Msg: "invalid chat-completions request: " + err.Error()}
 	}
-	return prompt, nil
+
+	return &types.LLMRequestBody{ChatCompletions: &chatCompletions}, nil
 }
 
-func constructChatMessage(role string, content string) string {
-	return fmt.Sprintf("
%s\n%s
\n", role, content)
+func validateChatCompletionsMessages(messages []types.Message) error {
+	if len(messages) == 0 {
+		return errutil.Error{Code: errutil.BadRequest, Msg: "chat-completions request must have at least one message"}
+	}
+
+	return nil
 }
diff --git a/pkg/generator/main.go b/pkg/generator/main.go
index 3cb70a5..c663588 100644
--- a/pkg/generator/main.go
+++ b/pkg/generator/main.go
@@ -35,6 +35,7 @@ import (
 func main() {
 	roots, err := loader.LoadRoots(
 		"k8s.io/apimachinery/pkg/runtime/schema", // Needed to parse generated register functions.
+		"sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha1",
 		"sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2",
 		"sigs.k8s.io/gateway-api-inference-extension/api/v1",
 	)
diff --git a/site-src/api-types/inferencemodel.md b/site-src/api-types/inferencemodel.md
deleted file mode 100644
index 54fe573..0000000
--- a/site-src/api-types/inferencemodel.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Inference Model
-
-??? example "Alpha since v0.1.0"
-
-    The `InferenceModel` resource is alpha and may have breaking changes in
-    future releases of the API.
-
-## Background
-
-An InferenceModel allows the Inference Workload Owner to define:
-
-- Which Model/LoRA adapter(s) to consume.
-  - Mapping from a client facing model name to the target model name in the InferencePool.
-  - InferenceModel allows for traffic splitting between adapters _in the same InferencePool_ to allow for new LoRA adapter versions to be easily rolled out.
-- Criticality of the requests to the InferenceModel.
-
-## Spec
-
-The full spec of the InferenceModel is defined [here](/reference/spec/#inferencemodel).
\ No newline at end of file
diff --git a/site-src/api-types/inferenceobjective.md b/site-src/api-types/inferenceobjective.md
new file mode 100644
index 0000000..8c48651
--- /dev/null
+++ b/site-src/api-types/inferenceobjective.md
@@ -0,0 +1,18 @@
+# Inference Objective
+
+??? example "Alpha since v1.0.0"
+
+    The `InferenceObjective` resource is alpha and may have breaking changes in
+    future releases of the API.
+
+## Background
+
+The **InferenceObjective** API defines a set of serving objectives of the specific request it is associated with. This CRD currently houses only `Priority` but will be expanded to include fields such as SLO attainment.
+
+## Usage
+
+To associate a request to the InferencePool with a specific InferenceObjective, the system uses a specific header: `x-gateway-inference-objective` with the value of the header set to the InferenceObjective metadata name. So the calling client must set the header key/value on the request to associate the selected InferenceObjective. If no InferenceObjective is selected, default values are used.  
+
+## Spec
+
+The full spec of the InferenceObjective is defined [here](/reference/x-v1-a2-spec/#inferenceobjective).
diff --git a/site-src/api-types/inferencepool.md b/site-src/api-types/inferencepool.md
index c4481b1..8922d0d 100644
--- a/site-src/api-types/inferencepool.md
+++ b/site-src/api-types/inferencepool.md
@@ -1,9 +1,8 @@
 # Inference Pool
 
-??? example "Alpha since v0.1.0"
+??? success example "GA since v1.0.0"
 
-    The `InferencePool` resource is alpha and may have breaking changes in
-    future releases of the API.
+    The `InferencePool` resource has been graduated to v1 and is considered stable.
 
 ## Background
 
diff --git a/site-src/api-types/inferencepoolimport.md b/site-src/api-types/inferencepoolimport.md
new file mode 100644
index 0000000..aa58247
--- /dev/null
+++ b/site-src/api-types/inferencepoolimport.md
@@ -0,0 +1,26 @@
+# Inference Pool Import
+
+??? example "Alpha since v1.1.0"
+
+    The `InferencePoolImport` resource is alpha and may have breaking changes in
+    future releases of the API.
+
+## Background
+
+The **InferencePoolImport** API is a cluster-local, controller-managed resource that represents an imported InferencePool.
+It primarily communicates a relationship between an exported InferencePool and the exporting cluster name. It is not
+user-authored; status carries the effective import. Inference Platform Owners can reference the InferencePoolImport,
+even if the local cluster does not have an InferencePool. In the context of Gateway API, it means that an HTTPRoute can
+be configured to reference an InferencePoolImport to route matching requests to endpoints of backing InferencePools.
+
+Key ideas:
+
+- Map an exported InferencePool to exporting controller and cluster.
+- Name/namespace sameness with the exported InferencePool (avoids extra indirection).
+- Conditions: Surface a controller-level status condition to indicate whether the InferencePoolImport is ready for use.
+- Conditions: Surface parent-level status conditions to indicate whether the InferencePoolImport is referenced by a parent,
+  e.g. Gateway.
+
+## Spec
+
+The full spec of the InferencePoolImport is defined [here](/reference/x-v1a1-spec/#inferencepoolimport).
diff --git a/site-src/concepts/api-overview.md b/site-src/concepts/api-overview.md
index ab07a1d..01ee254 100644
--- a/site-src/concepts/api-overview.md
+++ b/site-src/concepts/api-overview.md
@@ -23,6 +23,6 @@ each aligning with a specific user persona in the Generative AI serving workflow
 
 InferencePool represents a set of Inference-focused Pods and an extension that will be used to route to them. Within the broader Gateway API resource model, this resource is considered a "backend". In practice, that means that you'd replace a Kubernetes Service with an InferencePool. This resource has some similarities to Service (a way to select Pods and specify a port), but has some unique capabilities. With InferencePool, you can configure a routing extension as well as inference-specific routing optimizations. For more information on this resource, refer to our [InferencePool documentation](/api-types/inferencepool) or go directly to the [InferencePool spec](/reference/spec/#inferencepool).
 
-### InferenceModel
+### InferenceObjective
 
-An InferenceModel represents a model or adapter, and configuration associated with that model. This resource enables you to configure the relative criticality of a model, and allows you to seamlessly translate the requested model name to one or more backend model names. Multiple InferenceModels can be attached to an InferencePool. For more information on this resource, refer to our [InferenceModel documentation](/api-types/inferencemodel) or go directly to the [InferenceModel spec](/reference/spec/#inferencemodel).
+An InferenceObjective represents the objectives of a specific request. A single InferenceObjective is associated with a request, and multiple requests with different InferenceObjectives can be attached to an InferencePool. For more information on this resource, refer to our [InferenceObjective documentation](/api-types/inferenceobjective) or go directly to the [InferenceObjective spec](/reference/spec/#inferenceobjective).
diff --git a/site-src/concepts/priority-and-capacity.md b/site-src/concepts/priority-and-capacity.md
new file mode 100644
index 0000000..367aebf
--- /dev/null
+++ b/site-src/concepts/priority-and-capacity.md
@@ -0,0 +1,17 @@
+# Priority and Capacity
+
+The InferenceObjective creates the definition of `Priority` which describes how requests interact with each other, this naturally interacts with total pool capacity, and properly understanding and configuring these behaviors is important in allowing a pool to handle requests of different priority.
+
+## Priority (in flow control)
+
+It should be noted that priority is currently only used in [Capacity](#capacity), and that the description below is how Priority will be consumed in the `Flow Control` model.
+
+Priority is a simple stack rank; the higher the number, the higher the priority. Should no priority for a request be specified, the default value is zero. Requests of higher priority are _always_ selected first when requests are queued. Requests of equal priority currently operate on a FCFS basis. 
+
+## Capacity
+
+The current capacity model uses configurable [thresholds](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/35b14a10a9830d1a9e3850913539066ebc8fb317/pkg/epp/saturationdetector/saturationdetector.go#L49) to determine if the entire pool is saturated. The calculation is to simply iterate through each endpoint in the pool, and if all are above all thresholds, the pool is considered `saturated`. In the event of saturation, all requests with a negative priority will be rejected, and other requests will be scheduled and queued on the model servers. 
+
+## Future work
+
+The Flow Control system is nearing completion and will add more nuance to the Priority and Capacity model: proper priority enforcement, more articulate capacity tracking, queuing at the Inference Gateway level, etc. This documentation will be updated when the Flow Control has finished implementation.
\ No newline at end of file
diff --git a/site-src/concepts/roles-and-personas.md b/site-src/concepts/roles-and-personas.md
index 0746adb..f1d17a5 100644
--- a/site-src/concepts/roles-and-personas.md
+++ b/site-src/concepts/roles-and-personas.md
@@ -17,7 +17,7 @@ The Inference Platform Admin creates and manages the infrastructure necessary to
 
 An Inference Workload Owner persona owns and manages one or many Generative AI Workloads (LLM focused *currently*). This includes:
 
-- Defining criticality
+- Defining priority
 - Managing fine-tunes
   - LoRA Adapters
   - System Prompts
diff --git a/site-src/contributing/index.md b/site-src/contributing/index.md
index 7f56b82..eb5da17 100644
--- a/site-src/contributing/index.md
+++ b/site-src/contributing/index.md
@@ -46,4 +46,4 @@ doc. Feel free to add topics for discussion at an upcoming meeting.
 
 All meetings are recorded and automatically uploaded to the [WG-Serving meetings
 YouTube
-playlist](https://www.youtube.com/playlist?list=PL69nYSiGNLP30qNanabU75ayPK7OPNAAS).
+playlist](https://www.youtube.com/playlist?list=PL69nYSiGNLP2io2Gg92njBfh-DX9sk7O3).
diff --git a/site-src/enhancements/overview.md b/site-src/enhancements/overview.md
new file mode 100644
index 0000000..ad2355e
--- /dev/null
+++ b/site-src/enhancements/overview.md
@@ -0,0 +1,6 @@
+# Inference Gateway Proposal process
+
+Our current proposal process is intentionally light-weight. If you have a proposal you are interested in sharing, please follow these steps:
+
+1. Cut an issue or bring a topic to the weekly meeting!
+2. Assuming positive signal, or if more context is needed please add a proposal, following the style and naming conventions shown here: https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals
\ No newline at end of file
diff --git a/site-src/faq.md b/site-src/faq.md
index 99175c5..c24bfff 100644
--- a/site-src/faq.md
+++ b/site-src/faq.md
@@ -5,26 +5,29 @@ The [contributing](/contributing) page keeps track of how to get involved with
 the project.
 
 ## Why isn't this project in the main Gateway API repo?
-This project is an extension of Gateway API, and may eventually be merged into
-the main Gateway API repo. As we're starting, this project represents a close
-collaboration between
+This project builds on top of Gateway API, however, the Gateway API 
+[repo](https://github.com/kubernetes-sigs/gateway-api) is, as the name implies,
+an API definition, and does not contain deployables. Inference Gateway deviates
+from this; with the EPP & BBR deployables, and projects (like 
+[llm-d](https://github.com/llm-d)) depending on these binaries, merging this into
+the Gateway API repo would deviate from how that repo operates. 
+
+Additionally, this project represents a close collaboration between
 [WG-Serving](https://github.com/kubernetes/community/tree/master/wg-serving),
 [SIG-Network](https://github.com/kubernetes/community/tree/master/sig-network),
 and the [Gateway API](https://gateway-api.sigs.k8s.io/) subproject. These groups
 are all well represented within the ownership of this project, and the separate
 repo enables this group to iterate more quickly as this project is getting
-started. As the project stabilizes, we'll revisit if it should become part of
+started.  As the project stabilizes, we'll revisit if it should become part of
 the main Gateway API project.
 
 ## Will there be a default controller implementation?
 No. Although this project will provide a default/reference implementation of an
 extension, each individual Gateway controller can support this pattern. The
 scope of this project is to define the API extension model, a reference
-extension, conformance tests, and overall documentation.
+extension, conformance tests, and overall documentation. 
+
+A default controller for CRDs that do not have a Gateway dependency may be considered in the future.
 
-## Can you add support for my use case to the reference extension?
-Maybe. We're trying to keep the scope of the reference extension fairly narrow
-and instead hoping to see an ecosystem of compatible extensions developed in
-this space. Unless a use case fits neatly into the existing scope of our
-reference extension, it would likely be better to develop a separate extension
-focused on your use case.
+## Can you add support for my use case?
+Definitely. We are always happy to accept proposals to improving inference capabilities! However, the extensible and pluggable architecture of the EPP allows you to add it yourself, benchmark the capabilities, and then share those with the community. If you are looking for a place for more experimental features, [llm-d](https://github.com/llm-d) is a great place for incubation, many ideas and optimizations that start there, graduate to this repo. Additionally, many of us that work on this project, work there as well!
diff --git a/site-src/gieps/giep-116/index.md b/site-src/gieps/giep-116/index.md
deleted file mode 100644
index 4d678da..0000000
--- a/site-src/gieps/giep-116/index.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# GIEP-116: GIEP template
-
-* Issue: [#0](https://github.com/kubernetes-sigs/gateway-api-inference-extension/issues/116)
-* Status: Provisional|Implementable|Experimental|Standard|Deferred|Rejected|Withdrawn|Replaced
-
-(See status definitions [here](overview.md#status).)
-
-## TLDR
-
-(1-2 sentence summary of the proposal)
-
-## Goals
-
-(Primary goals of this proposal.)
-
-## Non-Goals
-
-(What is out of scope for this proposal.)
-
-## Introduction
-
-(Can link to external doc -- but we should bias towards copying
-the content into the GEP as online documents are easier to lose
--- e.g. owner messes up the permissions, accidental deletion)
-
-## API
-
-(... details, can point to PR with changes)
-
-## Conformance Details
-
-(This section describes the names to be used for the feature or
-features in conformance tests and profiles.
-
-These should be `CamelCase` names that specify the feature as
-precisely as possible, and are particularly important for
-Extended features, since they may be surfaced to users.)
-
-## Alternatives
-
-(List other design alternatives and why we did not go in that
-direction)
-
-## References
-
-(Add any additional document links. Again, we should try to avoid
-too much content not in version control to avoid broken links)
diff --git a/site-src/gieps/giep-116/metadata.yaml b/site-src/gieps/giep-116/metadata.yaml
deleted file mode 100644
index 56d1018..0000000
--- a/site-src/gieps/giep-116/metadata.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-apiVersion: internal.gateway.networking.k8s.io/v1alpha1
-kind: GIEPDetails
-number: 116
-name: GIEP template
-status: Completed
-# Any authors who contribute to the GEP in any way should be listed here using
-# their Github handle.
-authors:
-  - robscott
-relationships:
-  # obsoletes indicates that a GEP makes the linked GEP obsolete, and completely
-  # replaces that GEP. The obsoleted GEP MUST have its obsoletedBy field
-  # set back to this GEP, and MUST be moved to Declined.
-  obsoletes: {}
-  obsoletedBy: {}
-  # extends indicates that a GEP extends the linkned GEP, adding more detail
-  # or additional implementation. The extended GEP MUST have its extendedBy
-  # field set back to this GEP.
-  extends: {}
-  extendedBy: {}
-  # seeAlso indicates other GEPs that are relevant in some way without being
-  # covered by an existing relationship.
-  seeAlso: {}
-# references is a list of hyperlinks to relevant external references.
-# It's intended to be used for storing Github discussions, Google docs, etc.
-references: {}
-# featureNames is a list of the feature names introduced by the GEP, if there
-# are any. This will allow us to track which feature was introduced by which GEP.
-featureNames: {}
-# changelog is a list of hyperlinks to PRs that make changes to the GEP, in
-# ascending date order.
-changelog: {}
diff --git a/site-src/gieps/overview.md b/site-src/gieps/overview.md
deleted file mode 100644
index 438a0ff..0000000
--- a/site-src/gieps/overview.md
+++ /dev/null
@@ -1,272 +0,0 @@
-# Gateway Inference Enhancement Proposal (GIEP)
-
-Gateway Inference Enhancement Proposals (GIEPs) serve a similar purpose to the
-[GIEP](https://gateway-api.sigs.k8s.io/GIEPs/overview/) process for the main
-Gateway API project:
-
-1. Ensure that changes to the API follow a known process and discussion in the
-  OSS community.
-1. Make changes and proposals discoverable (current and future).
-1. Document design ideas, tradeoffs, decisions that were made for historical
-  reference.
-1. Record the results of larger community discussions.
-1. Record changes to the GIEP process itself.
-
-## Process
-
-This diagram shows the state diagram of the GIEP process at a high level, but
-the details are below.
-
-<div align="center">
-
-```mermaid
-flowchart TD
-    D([Discuss with<br />the community]) --> C
-    C([Issue Created]) -------> Memorandum
-    C([Issue Created]) --> Provisional
-    Provisional -->|If practical <br /> work needed| Prototyping
-    Provisional -->|GIEP Doc PR<br />done| Implementable
-    Prototyping -->|GIEP Doc PR<br />done| Implementable
-    Implementable -->|Gateway API<br />work completed| Experimental
-    Experimental -->|Supported in<br />multiple implementations<br />+ Conformance tests| Standard
-    Standard -->|Entire change is GA or implemented| Completed
-```
-
-</div>
-
-## GIEP Definitions
-
-### GIEP States
-
-Each GIEP has a state, which tracks where it is in the GIEP process.
-
-GIEPs can move to some states from any other state:
-
-  * **Declined**: The GIEP has been declined and further work will not occur.
-  * **Deferred:** We do not currently have bandwidth to handle this GIEP, it may
-    be revisited in the future.
-  * **Declined:** This proposal was considered by the community but ultimately
-  rejected.
-  * **Withdrawn:** This proposal was considered by the community but ultimately
-  withdrawn by the author.
-
-There is a special state to cover Memorandum GIEPs:
-
-  * **Memorandum**: These GIEPs either:
-    * Document an agreement for further work, creating no spec changes
-      themselves, or
-    * Update the GIEP process.
-
-API GIEPs flow through a number of states, which generally correspond to the
-level of stability of the change described in the GIEP:
-
-  * **Provisional:** The goals described by this GIEP have consensus but
-    implementation details have not been agreed to yet.
-  * **Prototyping:** An extension of `Provisional` which can be opted in to in
-    order to indicate to the community that there are some active practical
-    tests and experiments going on which are intended to be a part of the
-    development of this GIEP. This may include APIs or code, but that content
-    _must_ not be distributed with releases.
-  * **Implementable:** The goals and implementation details described by this
-    GIEP have consensus but have not been fully implemented yet.
-  * **Experimental:** This GIEP has been implemented and is part of the
-    "Experimental" release channel. Breaking changes are still possible, up to
-    and including complete removal and moving to `Rejected`.
-  * **Standard:** This GIEP has been implemented and is part of the "Standard"
-    release channel. It should be quite stable.
-  * **Completed**: All implementation work on this API GIEP has been completed.
-
-### Relationships between GIEPs
-
-GIEPs can have relationships between them. At this time, there are three
-possible relationships:
-
-* **Obsoletes** and its backreference **ObsoletedBy**: when a GIEP is made
-  obsolete by another GIEP, and has its functionality completely replaced. The
-  Obsoleted GIEP is moved to the **Declined** state.
-* **Extends** and its backreference **ExtendedBy**: when a GIEP has additional
-  details or implementation added in another GIEP.
-* **SeeAlso**: when a GIEP is relevant to another GIEP, but is not affected in
-  any other defined way.
-
-Relationships are tracked in the YAML metadata files accompanying each GIEP.
-
-### GIEP metadata file
-
-Each GIEP has a YAML file containing metadata alongside it, please keep it up to
-date as changes to the GIEP occur.
-
-In particular, note the `authors`, and `changelog` fields, please keep those up
-to date.
-
-## Process
-
-### 1. Discuss with the community
-
-Before creating a GIEP, share your high level idea with the community. There are
-several places this may be done:
-
-- A [new GitHub
-  Discussion](https://github.com/kubernetes-sigs/gateway-api/discussions/new)
-- On our [Slack Channel](https://kubernetes.slack.com/archives/CR0H13KGA)
-- On one of our [community
-  meetings](https://gateway-api.sigs.k8s.io/contributing/?h=meetings#meetings)
-
-Please default to GitHub discussions: they work a lot like GitHub issues which
-makes them easy to search.
-
-### 2. Create an Issue
-[Create a GIEP
-issue](https://github.com/kubernetes-sigs/gateway-api/issues/new?assignees=&labels=kind%2Ffeature&template=enhancement.md)
-in the repo describing your change. At this point, you should copy the outcome
-of any other conversations or documents into this document.
-
-### 3. Agree on the Goals
-Although it can be tempting to start writing out all the details of your
-proposal, it's important to first ensure we all agree on the goals.
-
-For API GIEPs, the first version of your GIEP should aim for a "Provisional"
-status and leave out any implementation details, focusing primarily on "Goals"
-and "Non-Goals".
-
-For Memorandum GIEPs, the first version of your GIEP will be the only one, as
-Memorandums have only a single stage - `Accepted`.
-
-### 3. Document Implementation Details
-Now that everyone agrees on the goals, it is time to start writing out your
-proposed implementation details. These implementation details should be very
-thorough, including the proposed API spec, and covering any relevant edge cases.
-Note that it may be helpful to use a shared doc for part of this phase to enable
-faster iteration on potential designs.
-
-It is likely that throughout this process, you will discuss a variety of
-alternatives. Be sure to document all of these in the GIEP, and why we decided
-against them. At this stage, the GIEP should be targeting the "Implementable"
-stage.
-
-### 4. Implement the GIEP as "Experimental"
-
-With the GIEP marked as "Implementable", it is time to actually make those
-proposed changes in our API. In some cases, these changes will be documentation
-only, but in most cases, some API changes will also be required. It is important
-that every new feature of the API is marked as "Experimental" when it is
-introduced. Within the API, we use `<gateway:experimental>` tags to denote
-experimental fields. Within Golang packages (conformance tests, CLIs, e.t.c.) we
-use the `experimental` Golang build tag to denote experimental functionality.
-
-Some other requirements must be met before marking a GIEP `Experimental`:
-
-- the graduation criteria to reach `Standard` MUST be filled out
-- a proposed probationary period (see next section) must be included in the GIEP
-  and approved by maintainers.
-
-Before changes are released they MUST be documented. GIEPs that have not been
-both implemented and documented before a release cut off will be excluded from
-the release.
-
-#### Probationary Period
-
-Any GIEP in the `Experimental` phase is automatically under a "probationary
-period" where it will come up for re-assessment if its graduation criteria are
-not met within a given time period. GIEPs that wish to move into `Experimental`
-status MUST document a proposed period (6 months is the suggested default) that
-MUST be approved by maintainers. Maintainers MAY select an alternative time
-duration for a probationary period if deemed appropriate, and will document
-their reasoning.
-
-> **Rationale**: This probationary period exists to avoid GIEPs getting "stale"
-> and to provide guidance to implementations about how relevant features should
-> be used, given that they are not guaranteed to become supported.
-
-At the end of a probationary period if the GIEP has not been able to resolve its
-graduation criteria it will move to "Rejected" status. In extenuating
-circumstances an extension of that period may be accepted by approval from
-maintainers. GIEPs which are `Rejected` in this way are removed from the
-experimental CRDs and more or less put on hold. GIEPs may be allowed to move
-back into `Experimental` status from `Rejected` for another probationary period
-if a new strategy for achieving their graduation criteria can be established.
-Any such plan to take a GIEP "off the shelf" must be reviewed and accepted by
-the maintainers.
-
-> **Warning**: It is extremely important** that projects which implement
-> `Experimental` features clearly document that these features may be removed in
-> future releases.
-
-### 5. Graduate the GIEP to "Standard"
-
-Once this feature has met the [graduation
-criteria](/concepts/versioning/#graduation-criteria), it is time to graduate it
-to the "Standard" channel of the API. Depending on the feature, this may include
-any of the following:
-
-1. Graduating the resource to beta
-2. Graduating fields to "standard" by removing `<gateway:experimental>` tags
-3. Graduating a concept to "standard" by updating documentation
-
-### 6. Close out the GIEP issue
-
-The GIEP issue should only be closed once the feature has:
-- Moved to the standard channel for distribution (if necessary)
-- Moved to a "v1" `apiVersion` for CRDs
-- been completely implemented and has wide acceptance (for process changes).
-
-In short, the GIEP issue should only be closed when the work is "done" (whatever
-that means for that GIEP).
-
-## Format
-
-GIEPs should match the format of the template found in
-[GIEP-696](/GIEPs/GIEP-696).
-
-## Out of scope
-
-What is out of scope: see [text from KEP][kep-when-to-use]. Examples:
-
-* Bug fixes
-* Small changes (API validation, documentation, fixups). It is always possible
-  that the reviewers will determine a "small" change ends up requiring a GIEP.
-
-## FAQ
-
-#### Why is it named GIEP?
-To avoid potential confusion if people start following the cross references to
-the full GEP or KEP process.
-
-#### Why have a different process than mainline?
-Gateway API has some differences with most upstream KEPs. Notably Gateway API
-intentionally avoids including any implementation with the project, so this
-process is focused entirely on the substance of the API. As this project is
-based on CRDs it also has an entirely separately release process, and has
-developed concepts like "release channels" that do not exist in upstream.
-
-#### Is it ok to discuss using shared docs, scratch docs etc?
-Yes, this can be a helpful intermediate step when iterating on design details.
-It is important that all major feedback, discussions, and alternatives
-considered in that step are represented in the GIEP though. A key goal of GIEPs
-is to show why we made a decision and which alternatives were considered. If
-separate docs are used, it's important that we can still see all relevant
-context and decisions in the final GIEP.
-
-#### When should I mark a GIEP as `Prototyping` as opposed to `Provisional`?
-The `Prototyping` status carries the same base meaning as `Provisional` in that
-consensus is not complete between stakeholders and we're not ready to move
-toward releasing content yet. You should use `Prototyping` to indicate to your
-fellow community members that we're in a state of active practical tests and
-experiments which are intended to help us learn and iterate on the GIEP. These
-can include distributing content, but not under any release channel.
-
-#### Should I implement support for `Experimental` channel features?
-Ultimately one of the main ways to get something into `Standard` is for it to
-mature through the `Experimental` phase, so we really _need_ people to implement
-these features and provide feedback in order to have progress. That said, the
-graduation of a feature past `Experimental` is not a forgone conclusion. Before
-implementing an experimental feature, you should:
-
-* Clearly document that support for the feature is experimental and may
-  disappear in the future.
-* Have a plan in place for how you would handle the removal of this feature from
-  the API.
-
-[kep]: https://github.com/kubernetes/enhancements
-[kep-when-to-use]:
-    https://github.com/kubernetes/enhancements/tree/master/keps#do-i-have-to-use-the-kep-process
diff --git a/site-src/guides/adapter-rollout.md b/site-src/guides/adapter-rollout.md
index 0936d29..7d6611c 100644
--- a/site-src/guides/adapter-rollout.md
+++ b/site-src/guides/adapter-rollout.md
@@ -3,7 +3,6 @@
 The goal of this guide is to show you how to perform incremental roll out operations,
 which gradually deploy new versions of your inference infrastructure.
 You can update LoRA adapters and Inference Pool with minimal service disruption.
-This page also provides guidance on traffic splitting and rollbacks to help ensure reliable deployments for LoRA adapters rollout.
 
 LoRA adapter rollouts let you deploy new versions of LoRA adapters in phases,
 without altering the underlying base model or infrastructure.
@@ -49,36 +48,7 @@ data:
 
 The new adapter version is applied to the model servers live, without requiring a restart.
 
-
-### Direct traffic to the new adapter version
-
-Modify the InferenceModel to configure a canary rollout with traffic splitting. In this example, 10% of traffic for food-review model will be sent to the new ***food-review-2*** adapter.
-
-
-```bash
-kubectl edit inferencemodel food-review
-```
-
-Change the targetModels list in InferenceModel to match the following:
-
-
-```yaml
-apiVersion: inference.networking.x-k8s.io/v1alpha2
-kind: InferenceModel
-metadata:
-  name: food-review
-spec:
-  criticality: 1
-  poolRef:
-    name: vllm-llama3-8b-instruct
-  targetModels:
-  - name: food-review-1
-    weight: 90
-  - name: food-review-2
-    weight: 10
-```
-
-The above configuration means one in every ten requests should be sent to the new version. Try it out:
+Try it out:
 
 1. Get the gateway IP:
 ```bash
@@ -88,7 +58,7 @@ IP=$(kubectl get gateway/inference-gateway -o jsonpath='{.status.addresses[0].va
 2. Send a few requests as follows:
 ```bash
 curl -i ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -d '{
-"model": "food-review",
+"model": "food-review-2",
 "prompt": "Write as if you were a critic: San Francisco",
 "max_tokens": 100,
 "temperature": 0
@@ -97,23 +67,6 @@ curl -i ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -d '{
 
 ### Finish the rollout
 
-
-Modify the InferenceModel to direct 100% of the traffic to the latest version of the adapter.
-
-```yaml
-apiVersion: inference.networking.x-k8s.io/v1alpha2
-kind: InferenceModel
-metadata:
-  name: food-review
-spec:
-  criticality: 1
-  poolRef:
-    name: vllm-llama3-8b-instruct
-  targetModels:
-  - name: food-review-2
-    weight: 100
-```
-
 Unload the older versions from the servers by updating the LoRA syncer ConfigMap to list the older version under the `ensureNotExist` list:
 
 ```yaml
@@ -137,5 +90,5 @@ data:
           source: Kawon/llama3.1-food-finetune_v14_r8
 ```
 
-With this, all requests should be served by the new adapter version.
+With this, the new adapter version should be available for all incoming requests.
 
diff --git a/site-src/guides/epp-configuration/config-text.md b/site-src/guides/epp-configuration/config-text.md
index 6df19db..43a0e6c 100644
--- a/site-src/guides/epp-configuration/config-text.md
+++ b/site-src/guides/epp-configuration/config-text.md
@@ -1,17 +1,14 @@
-# Configuring Plugins via text
+# Configuring Plugins via YAML
 
 The set of lifecycle hooks (plugins) that are used by the Inference Gateway (IGW) is determined by how
-it is configured. The IGW can be configured in several ways, either by code or via text.
+it is configured. The IGW is primarily configured via a configuration file.
 
-If configured by code either a set of predetermined environment variables must be used or one must
-fork the IGW and change code.
-
-A simpler way to congigure the IGW is to use a text based configuration. This text is in YAML format
-and can either be in a file or specified in-line as a parameter. The configuration defines the set of
+The YAML file can either be specified as a path to a file or in-line as a parameter. The configuration defines the set of
 plugins to be instantiated along with their parameters. Each plugin can also be given a name, enabling
-the same plugin type to be instantiated multiple times, if needed.
+the same plugin type to be instantiated multiple times, if needed (such as when configuring multiple scheduling profiles).
 
-Also defined is a set of SchedulingProfiles, which determine the set of plugins to be used when scheduling a request. If one is not defailed, a default one names `default` will be added and will reference all of the
+Also defined is a set of SchedulingProfiles, which determine the set of plugins to be used when scheduling a request.
+If no scheduling profile is specified, a default profile, named `default` will be added and will reference all of the
 instantiated plugins.
 
 The set of plugins instantiated can include a Profile Handler, which determines which SchedulingProfiles
@@ -22,12 +19,9 @@ In addition, the set of instantiated plugins can also include a picker, which ch
 the request is scheduled after filtering and scoring. If one is not referenced in a SchedulingProfile, an
 instance of `MaxScorePicker` will be added to the SchedulingProfile in question.
 
-It should be noted that while the configuration text looks like a Kubernetes Custom Resource, it is
-**NOT** a Kubernetes Custom Resource. Kubernetes infrastructure is used to load the configuration
-text and in the future will also help in versioning the text.
-
-It should also be noted that even when the configuration text is loaded from a file, it is loaded at
-the Endpoint-Picker's (EPP) startup and changes to the file at runtime are ignored.
+***NOTE***: While the configuration text looks like a Kubernetes CRD, it is
+**NOT** a Kubernetes CRD. Specifically, the config is not reconciled upon, and is only read on startup.
+This behavior is intentional, as augmenting the scheduling config without redeploying the EPP is not supported.
 
 The configuration text has the following form:
 ```yaml
@@ -91,7 +85,7 @@ kind: EndpointPickerConfig
 plugins:
 - type: prefix-cache-scorer
   parameters:
-    hashBlockSize: 5
+    blockSize: 5
     maxPrefixBlocksToMatch: 256
     lruCapacityPerServer: 31250
 schedulingProfiles:
@@ -158,7 +152,7 @@ spec:
           plugins:
           - type: prefix-cache-scorer
             parameters:
-              hashBlockSize: 5
+              blockSize: 5
               maxPrefixBlocksToMatch: 256
               lruCapacityPerServer: 31250
           schedulingProfiles:
@@ -177,7 +171,7 @@ kind: EndpointPickerConfig
 plugins:
 - type: prefix-cache-scorer
   parameters:
-    hashBlockSize: 5
+    blockSize: 5
     maxPrefixBlocksToMatch: 256
     lruCapacityPerServer: 31250
 - type: single-profile-handler
@@ -207,7 +201,7 @@ Scores pods based on the amount of the prompt is believed to be in the pod's KvC
 
 - *Type*: prefix-cache-scorer
 - *Parameters*:
-  - `hashBlockSize` specified the size of the blocks to break up the input prompt when
+  - `blockSize` specified the size of the blocks to break up the input prompt when
     calculating the block hashes. If not specified defaults to `64`
   - `maxPrefixBlocksToMatch` specifies the maximum number of prefix blocks to match. If
    not specified defaults to `256`
@@ -241,6 +235,15 @@ Picks a random pod from the list of candidates.
   - `maxNumOfEndpoints`: Maximum number of endpoints to pick from the list of candidates. If not
     specified defaults to `1`.
 
+#### **WeightedRandomPicker**
+
+Picks pod(s) from the list of candidates based on weighted random sampling using A-Res algorithm.
+
+- *Type*: weighted-random-picker
+- *Parameters*:
+  - `maxNumOfEndpoints`: Maximum number of endpoints to pick from the list of candidates. If not
+    specified defaults to `1`.
+
 #### **KvCacheScorer**
 
 Scores the candidate pods based on their KV cache utilization.
diff --git a/site-src/guides/epp-configuration/flags.md b/site-src/guides/epp-configuration/flags.md
new file mode 100644
index 0000000..7154668
--- /dev/null
+++ b/site-src/guides/epp-configuration/flags.md
@@ -0,0 +1,33 @@
+# EPP Configuration Flags
+
+This page documents selected configuration flags for the Endpoint Picker (EPP) binary. Most flags are self-explanatory via their `--help` descriptions; only flags with nuanced or non-obvious behavior are detailed here.
+
+## --pool-namespace
+
+**Description:**
+Specifies the namespace of the InferencePool this Endpoint Picker is associated with.
+
+**Resolution order:**
+1. If `--pool-namespace` is set to a non-empty value, its value is used.
+2. If the flag is not set (i.e., left empty), the `NAMESPACE` environment variable is checked. If set, its value is used.
+3. If neither is set, the namespace defaults to `default`.
+
+This allows the EPP to automatically use the namespace it is running in (when the `NAMESPACE` env var is set via Kubernetes Downward API), without requiring explicit configuration. If you want to force the use of the default namespace, explicitly set `--pool-namespace=default`. If you want to use the environment variable or fallback, leave the flag unset or set it to an empty string.
+
+**Example manifest snippet to set the env var from pod metadata:**
+
+```yaml
+env:
+  - name: NAMESPACE
+    valueFrom:
+      fieldRef:
+        fieldPath: metadata.namespace
+```
+
+---
+
+For a full list of flags, run:
+
+```
+EPP_BINARY --help
+```
diff --git a/site-src/guides/epp-configuration/prefix-aware.md b/site-src/guides/epp-configuration/prefix-aware.md
index 9c1074b..88573c4 100644
--- a/site-src/guides/epp-configuration/prefix-aware.md
+++ b/site-src/guides/epp-configuration/prefix-aware.md
@@ -14,7 +14,7 @@ Like any other plugins, the prefix cache aware plugin can be enabled/disabled vi
 
 The prefix cache plugin exposes the following advanced configuration parameters:
 
-* `hashBlockSize`: The plugin matches prefixes in the unit of blocks. This is the size
+* `blockSize`: The plugin matches prefixes in the unit of blocks. This is the size
 of each block in number of bytes. vLLM default block size is 16 tokens. Assume 4 characters per token, the default
 is set to 64 in EPP. The default is recommended unless performance is critical for use cases with
 extremely long inputs.
diff --git a/site-src/guides/implementers.md b/site-src/guides/implementers.md
index 6fce016..d42fa8d 100644
--- a/site-src/guides/implementers.md
+++ b/site-src/guides/implementers.md
@@ -157,8 +157,8 @@ An example of a similar approach is Kuadrant’s [WASM Shim](https://github.com/
 Here are some tips for testing your controller end-to-end:
 
 - **Focus on Key Scenarios**: Add common scenarios like creating, updating, and deleting InferencePool resources, as well as different routing rules that target InferencePool backends.
-- **Verify Routing Behaviors**: Design more complex routing scenarios and verify that requests are correctly routed to the appropriate model server pods within the InferencePool based on the InferenceModel configuration.
-- **Test Error Handling**: Verify that the controller correctly handles scenarios like unsupported model names or resource constraints (if criticality-based shedding is implemented). Test with state transitions (such as constant requests while Pods behind EPP are being replaced and Pods behind InferencePool are being replaced) to ensure that the system is resilient to failures and can automatically recover by redirecting traffic to healthy Pods.
+- **Verify Routing Behaviors**: Design more complex routing scenarios and verify that requests are correctly routed to the appropriate model server pods within the InferencePool.
+- **Test Error Handling**: Verify that the controller correctly handles scenarios like unsupported model names or resource constraints (if priority-based shedding is implemented). Test with state transitions (such as constant requests while Pods behind EPP are being replaced and Pods behind InferencePool are being replaced) to ensure that the system is resilient to failures and can automatically recover by redirecting traffic to healthy Pods.
 - **Using Reference EPP Implementation + Echoserver**: You can use the [reference EPP implementation](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/pkg/epp) for testing your controller end-to-end. Instead of a full-fledged model server, a simple mock server (like the [echoserver](https://github.com/kubernetes-sigs/ingress-controller-conformance/tree/master/images/echoserver)) can be very useful for verifying routing to ensure the correct pod received the request. 
 - **Performance Test**: Run end-to-end [benchmarks](https://gateway-api-inference-extension.sigs.k8s.io/performance/benchmark/) to make sure that your inference gateway can achieve the latency target that is desired.
 
diff --git a/site-src/guides/index.md b/site-src/guides/index.md
index e02ffb5..b0faa49 100644
--- a/site-src/guides/index.md
+++ b/site-src/guides/index.md
@@ -4,16 +4,20 @@
 
     This project is still in an alpha state and breaking changes may occur in the future.
 
+
 This quickstart guide is intended for engineers familiar with k8s and model servers (vLLM in this instance). The goal of this guide is to get an Inference Gateway up and running!
 
 ## **Prerequisites**
 
-- A cluster with:
+A cluster with:
   - Support for services of type `LoadBalancer`. For kind clusters, follow [this guide](https://kind.sigs.k8s.io/docs/user/loadbalancer)
   to get services of type LoadBalancer working.
   - Support for [sidecar containers](https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/) (enabled by default since Kubernetes v1.29)
   to run the model server deployment.
 
+Tooling:
+  - [Helm](https://helm.sh/docs/intro/install/) installed
+
 ## **Steps**
 
 ### Deploy Sample Model Server
@@ -33,41 +37,45 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
 
 === "GPU-Based Model Server"
 
-      For this setup, you will need 3 GPUs to run the sample model server. Adjust the number of replicas in `./config/manifests/vllm/gpu-deployment.yaml` as needed.
-      Create a Hugging Face secret to download the model [meta-llama/Llama-3.1-8B-Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct). Ensure that the token grants access to this model.
+    For this setup, you will need 3 GPUs to run the sample model server. Adjust the number of replicas in `./config/manifests/vllm/gpu-deployment.yaml` as needed.
+    Create a Hugging Face secret to download the model [meta-llama/Llama-3.1-8B-Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct). Ensure that the token grants access to this model.
 
-      Deploy a sample vLLM deployment with the proper protocol to work with the LLM Instance Gateway.
+    Deploy a sample vLLM deployment with the proper protocol to work with the LLM Instance Gateway.
 
-      ```bash
-      kubectl create secret generic hf-token --from-literal=token=$HF_TOKEN # Your Hugging Face Token with access to the set of Llama models
-      kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/gpu-deployment.yaml
-      ```
+    ```bash
+    kubectl create secret generic hf-token --from-literal=token=$HF_TOKEN # Your Hugging Face Token with access to the set of Llama models
+    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/gpu-deployment.yaml
+    ```
 
 === "CPU-Based Model Server"
 
-      This setup is using the formal `vllm-cpu` image, which according to the documentation can run vLLM on x86 CPU platform.
-      For this setup, we use approximately 9.5GB of memory and 12 CPUs for each replica.
+    ???+ warning
 
-      While it is possible to deploy the model server with less resources, this is not recommended. For example, in our tests, loading the model using 8GB of memory and 1 CPU was possible but took almost 3.5 minutes and inference requests took unreasonable time. In general, there is a tradeoff between the memory and CPU we allocate to our pods and the performance. The more memory and CPU we allocate the better performance we can get.
+        CPU deployment can be unreliable i.e. the pods may crash/restart because of resource contraints.
 
-      After running multiple configurations of these values we decided in this sample to use 9.5GB of memory and 12 CPUs for each replica, which gives reasonable response times. You can increase those numbers and potentially may even get better response times. For modifying the allocated resources, adjust the numbers in [cpu-deployment.yaml](https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/cpu-deployment.yaml) as needed.
+    This setup is using the formal `vllm-cpu` image, which according to the documentation can run vLLM on x86 CPU platform.
+    For this setup, we use approximately 9.5GB of memory and 12 CPUs for each replica.
 
-      Deploy a sample vLLM deployment with the proper protocol to work with the LLM Instance Gateway.
+    While it is possible to deploy the model server with less resources, this is not recommended. For example, in our tests, loading the model using 8GB of memory and 1 CPU was possible but took almost 3.5 minutes and inference requests took unreasonable time. In general, there is a tradeoff between the memory and CPU we allocate to our pods and the performance. The more memory and CPU we allocate the better performance we can get.
 
-      ```bash
-      kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/cpu-deployment.yaml
-      ```
+    After running multiple configurations of these values we decided in this sample to use 9.5GB of memory and 12 CPUs for each replica, which gives reasonable response times. You can increase those numbers and potentially may even get better response times. For modifying the allocated resources, adjust the numbers in [cpu-deployment.yaml](https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/cpu-deployment.yaml) as needed.
+
+    Deploy a sample vLLM deployment with the proper protocol to work with the LLM Instance Gateway.
+
+    ```bash
+    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/cpu-deployment.yaml
+    ```
 
 === "vLLM Simulator Model Server"
 
-      This option uses the [vLLM simulator](https://github.com/llm-d/llm-d-inference-sim/tree/main) to simulate a backend model server.
-      This setup uses the least amount of compute resources, does not require GPU's, and is ideal for test/dev environments.
+    This option uses the [vLLM simulator](https://github.com/llm-d/llm-d-inference-sim/tree/main) to simulate a backend model server.
+    This setup uses the least amount of compute resources, does not require GPU's, and is ideal for test/dev environments.
 
-      To deploy the vLLM simulator, run the following command.
+    To deploy the vLLM simulator, run the following command.
 
-      ```bash
-      kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/sim-deployment.yaml
-      ```
+    ```bash
+    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/sim-deployment.yaml
+    ```
 
 ### Install the Inference Extension CRDs
 
@@ -75,19 +83,57 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
    kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/latest/download/manifests.yaml
    ```
 
-### Deploy InferenceModel
+### Deploy the InferencePool and Endpoint Picker Extension
+
+   Install an InferencePool named `vllm-llama3-8b-instruct` that selects from endpoints with label `app: vllm-llama3-8b-instruct` and listening on port 8000. The Helm install command automatically installs the endpoint-picker, inferencepool along with provider specific resources.
 
-   Deploy the sample InferenceModel which is configured to forward traffic to the `food-review-1` [LoRA adapter](https://docs.vllm.ai/en/latest/features/lora.html) of the sample model server.
+=== "GKE"
 
-   ```bash
-   kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/refs/tags/v0.5.1/config/manifests/inferencemodel.yaml
-   ```
+      ```bash
+      export GATEWAY_PROVIDER=gke
+      export IGW_CHART_VERSION=v1.0.1
+      helm install vllm-llama3-8b-instruct \
+      --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
+      --set provider.name=$GATEWAY_PROVIDER \
+      --version $IGW_CHART_VERSION \
+      oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
+      ```
 
-### Deploy the InferencePool and Endpoint Picker Extension
+=== "Istio"
 
-   ```bash
-   kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/refs/tags/v0.5.1/config/manifests/inferencepool-resources.yaml
-   ```
+      ```bash
+      export GATEWAY_PROVIDER=istio
+      export IGW_CHART_VERSION=v1.0.1
+      helm install vllm-llama3-8b-instruct \
+      --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
+      --set provider.name=$GATEWAY_PROVIDER \
+      --version $IGW_CHART_VERSION \
+      oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
+      ```
+
+=== "Kgateway"
+
+      ```bash
+      export GATEWAY_PROVIDER=none
+      export IGW_CHART_VERSION=v1.0.1
+      helm install vllm-llama3-8b-instruct \
+      --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
+      --set provider.name=$GATEWAY_PROVIDER \
+      --version $IGW_CHART_VERSION \
+      oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
+      ```
+
+=== "Agentgateway"
+
+      ```bash
+      export GATEWAY_PROVIDER=none
+      export IGW_CHART_VERSION=v1.0.1
+      helm install vllm-llama3-8b-instruct \
+      --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
+      --set provider.name=$GATEWAY_PROVIDER \
+      --version $IGW_CHART_VERSION \
+      oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
+      ```
 
 ### Deploy an Inference Gateway
 
@@ -95,23 +141,23 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
 
 === "GKE"
 
-      1. Enable the Gateway API and configure proxy-only subnets when necessary. See [Deploy Gateways](https://cloud.google.com/kubernetes-engine/docs/how-to/deploying-gateways)
-      for detailed instructions.
+      1. Enable the Google Kubernetes Engine API, Compute Engine API, the Network Services API and configure proxy-only subnets when necessary. 
+         See [Deploy Inference Gateways](https://cloud.google.com/kubernetes-engine/docs/how-to/deploy-gke-inference-gateway)
+         for detailed instructions.
 
-      1. Deploy Gateway and HealthCheckPolicy resources
+      2. Deploy Inference Gateway:
 
          ```bash
          kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/gateway.yaml
-         kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/healthcheck.yaml
          ```
 
          Confirm that the Gateway was assigned an IP address and reports a `Programmed=True` status:
+
          ```bash
          $ kubectl get gateway inference-gateway
          NAME                CLASS               ADDRESS         PROGRAMMED   AGE
          inference-gateway   inference-gateway   <MY_ADDRESS>    True         22s
          ```
-
       3. Deploy the HTTPRoute
 
          ```bash
@@ -123,13 +169,7 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
          ```bash
          kubectl get httproute llm-route -o yaml
          ```
-
-      5. Given that the default connection timeout may be insufficient for most inference workloads, it is recommended to configure a timeout appropriate for your intended use case.
-
-         ```bash
-         kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/gcp-backend-policy.yaml
-         ```
-
+   
 === "Istio"
 
       Please note that this feature is currently in an experimental phase and is not intended for production use.
@@ -142,7 +182,7 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
       2. Install Istio
 
          ```
-         TAG=$(curl https://storage.googleapis.com/istio-build/dev/1.27-dev)
+         TAG=$(curl https://storage.googleapis.com/istio-build/dev/1.28-dev)
          # on Linux
          wget https://storage.googleapis.com/istio-build/dev/$TAG/istioctl-$TAG-linux-amd64.tar.gz
          tar -xvf istioctl-$TAG-linux-amd64.tar.gz
@@ -156,13 +196,7 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
          ./istioctl install --set tag=$TAG --set hub=gcr.io/istio-testing --set values.pilot.env.ENABLE_GATEWAY_API_INFERENCE_EXTENSION=true
          ```
 
-      3. If you run the Endpoint Picker (EPP) with the `--secure-serving` flag set to `true` (the default mode), it is currently using a self-signed certificate. As a security measure, Istio does not trust self-signed certificates by default. As a temporary workaround, you can apply the destination rule to bypass TLS verification for EPP. A more secure TLS implementation in EPP is being discussed in [Issue 582](https://github.com/kubernetes-sigs/gateway-api-inference-extension/issues/582).
-
-         ```bash
-         kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/istio/destination-rule.yaml
-         ```
-
-      4. Deploy Gateway
+      3. Deploy Gateway
 
          ```bash
          kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/istio/gateway.yaml
@@ -175,13 +209,13 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
          inference-gateway   inference-gateway   <MY_ADDRESS>    True         22s
          ```
 
-      6. Deploy the HTTPRoute
+      4. Deploy the HTTPRoute
 
          ```bash
          kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/istio/httproute.yaml
          ```
 
-      7. Confirm that the HTTPRoute status conditions include `Accepted=True` and `ResolvedRefs=True`:
+      5. Confirm that the HTTPRoute status conditions include `Accepted=True` and `ResolvedRefs=True`:
 
          ```bash
          kubectl get httproute llm-route -o yaml
@@ -189,9 +223,8 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
 
 === "Kgateway"
 
-      [Kgateway](https://kgateway.dev/) recently added support for inference extension as a **technical preview**. This means do not
-      run Kgateway with inference extension in production environments. Refer to [Issue 10411](https://github.com/kgateway-dev/kgateway/issues/10411)
-      for the list of caveats, supported features, etc.
+      [Kgateway](https://kgateway.dev/) added Inference Gateway support as a **technical preview** in the
+      [v2.0.0 release](https://github.com/kgateway-dev/kgateway/releases/tag/v2.0.0). InferencePool v1.0.0 is currently supported in the latest [rolling release](https://github.com/kgateway-dev/kgateway/releases/tag/v2.1.0-main), which includes the latest changes but may be unstable until the [v2.1.0 release](https://github.com/kgateway-dev/kgateway/milestone/58) is published.
 
       1. Requirements
 
@@ -201,7 +234,7 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
       2. Set the Kgateway version and install the Kgateway CRDs.
 
          ```bash
-         KGTW_VERSION=v2.0.4
+         KGTW_VERSION=v2.1.0-main
          helm upgrade -i --create-namespace --namespace kgateway-system --version $KGTW_VERSION kgateway-crds oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds
          ```
 
@@ -238,7 +271,7 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
 
 === "Agentgateway"
 
-      [Agentgateway](https://agentgateway.dev/) is a purpose-built proxy designed for AI workloads, and comes with native support for inference routing. Agentgateway integrates with [Kgateway](https://kgateway.dev/) as it's control plane.
+      [Agentgateway](https://agentgateway.dev/) is a purpose-built proxy designed for AI workloads, and comes with native support for Inference Gateway. Agentgateway integrates with [Kgateway](https://kgateway.dev/) as it's control plane. InferencePool v1.0.0 is currently supported in the latest [rolling release](https://github.com/kgateway-dev/kgateway/releases/tag/v2.1.0-main), which includes the latest changes but may be unstable until the [v2.1.0 release](https://github.com/kgateway-dev/kgateway/milestone/58) is published.
 
       1. Requirements
 
@@ -248,7 +281,7 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
       2. Set the Kgateway version and install the Kgateway CRDs.
 
          ```bash
-         KGTW_VERSION=v2.0.4
+         KGTW_VERSION=v2.1.0-main
          helm upgrade -i --create-namespace --namespace kgateway-system --version $KGTW_VERSION kgateway-crds oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds
          ```
 
@@ -283,6 +316,14 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
          kubectl get httproute llm-route -o yaml
          ```
 
+### Deploy InferenceObjective (Optional)
+
+Deploy the sample InferenceObjective which allows you to specify priority of requests.
+
+   ```bash
+   kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/inferenceobjective.yaml
+   ```
+
 ### Try it out
 
    Wait until the gateway is ready.
@@ -292,57 +333,59 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
    PORT=80
 
    curl -i ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -d '{
-   "model": "food-review",
+   "model": "food-review-1",
    "prompt": "Write as if you were a critic: San Francisco",
    "max_tokens": 100,
    "temperature": 0
    }'
    ```
 
+### Deploy the Body Based Router Extension (Optional)
+
+This guide has shown how to get started with serving a single base model type per L7 URL path. If after this exercise, you wish to continue on to exercise model-aware routing such that more than 1 base model is served at the same L7 url path, that requires use of the (optional) Body Based Routing (BBR) extension which is described in a separate section of the documentation, namely the [`Serving Multiple GenAI Models`](serve-multiple-genai-models.md) section. If you wish to exercise that function, then retain the setup you have deployed so far from this guide and move on to the additional steps described in [that guide](serve-multiple-genai-models.md) or else move on to the following section to cleanup your setup. 
+
 ### Cleanup
 
    The following instructions assume you would like to cleanup ALL resources that were created in this quickstart guide.
    Please be careful not to delete resources you'd like to keep.
 
-   1. Uninstall the InferencePool, InferenceModel, and model server resources
+   1. Uninstall the InferencePool, InferenceObjective and model server resources
 
       ```bash
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/inferencepool-resources.yaml --ignore-not-found
+      helm uninstall vllm-llama3-8b-instruct
       kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/inferenceobjective.yaml --ignore-not-found
       kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/cpu-deployment.yaml --ignore-not-found
       kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/gpu-deployment.yaml --ignore-not-found
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/vllm/sim-deployment.yaml --ignore-not-found
       kubectl delete secret hf-token --ignore-not-found
       ```
 
-   1. Uninstall the Gateway API resources
-
-      ```bash
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/gateway.yaml --ignore-not-found
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/healthcheck.yaml --ignore-not-found
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/gcp-backend-policy.yaml --ignore-not-found
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/httproute.yaml --ignore-not-found
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/istio/gateway.yaml --ignore-not-found
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/istio/destination-rule.yaml --ignore-not-found
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/istio/httproute.yaml --ignore-not-found
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/kgateway/gateway.yaml --ignore-not-found
-      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/kgateway/httproute.yaml --ignore-not-found
-      ```
-
    1. Uninstall the Gateway API Inference Extension CRDs
 
       ```bash
       kubectl delete -k https://github.com/kubernetes-sigs/gateway-api-inference-extension/config/crd --ignore-not-found
       ```
-
+      
    1. Choose one of the following options to cleanup the Inference Gateway.
 
 === "GKE"
 
-      No further clean up is needed.
+      ```bash
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/gateway.yaml --ignore-not-found
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/healthcheck.yaml --ignore-not-found
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/gcp-backend-policy.yaml --ignore-not-found
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/gke/httproute.yaml --ignore-not-found
+      ```
 
 === "Istio"
 
-      The following instructions assume you would like to clean up ALL Istio resources that were created in this quickstart guide.
+      ```bash
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/istio/gateway.yaml --ignore-not-found
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/istio/destination-rule.yaml --ignore-not-found
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/istio/httproute.yaml --ignore-not-found
+      ```
+
+      The following steps assume you would like to clean up ALL Istio resources that were created in this quickstart guide.
 
       1. Uninstall All Istio resources
 
@@ -356,10 +399,14 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
          kubectl delete ns istio-system
          ```
 
-
 === "Kgateway"
 
-      The following instructions assume you would like to cleanup ALL Kgateway resources that were created in this quickstart guide.
+      ```bash
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/kgateway/gateway.yaml --ignore-not-found
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/kgateway/httproute.yaml --ignore-not-found
+      ```
+
+      The following steps assume you would like to cleanup ALL Kgateway resources that were created in this quickstart guide.
 
       1. Uninstall Kgateway
 
@@ -381,7 +428,12 @@ This quickstart guide is intended for engineers familiar with k8s and model serv
 
 === "Agentgateway"
 
-      The following instructions assume you would like to cleanup ALL Kgateway resources that were created in this quickstart guide.
+      ```bash
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/kgateway/gateway.yaml --ignore-not-found
+      kubectl delete -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/gateway/kgateway/httproute.yaml --ignore-not-found
+      ```
+
+      The following steps assume you would like to cleanup ALL Kgateway resources that were created in this quickstart guide.
 
       1. Uninstall Kgateway
 
diff --git a/site-src/guides/inferencepool-rollout.md b/site-src/guides/inferencepool-rollout.md
index 98b3cc4..b274a72 100644
--- a/site-src/guides/inferencepool-rollout.md
+++ b/site-src/guides/inferencepool-rollout.md
@@ -34,7 +34,6 @@ teams can ensure stability and performance, quickly identifying and reverting an
 
 1. **Deploy new infrastructure**: Create a new InferencePool configured with the new node(compute/accelerator) / model server / base model that you chose.
 1. **Configure traffic splitting**: Use an HTTPRoute to split traffic between the existing InferencePool and the new InferencePool. The `backendRefs.weight` field controls the traffic percentage allocated to each pool.
-1. **Maintain InferenceModel integrity**: Retain the existing InferenceModel configuration to ensure uniform model behavior across both node configurations or base model versions or model server versions.
 1. **Preserve rollback capability**: Retain the original nodes and InferencePool during the roll out to facilitate a rollback if necessary.
 
 ## Example
@@ -45,276 +44,10 @@ Follow the steps in the [main guide](index.md)
 
 ### Deploy new infrastructure
 You start with an existing InferencePool named vllm-llama3-8b-instruct.
-To replace the original InferencePool, you create a new InferencePool named vllm-llama3-8b-instruct-new along with
-InferenceModels and Endpoint Picker Extension configured with the updated node specifications of `nvidia-h100-80gb` accelerator type,
+To replace the original InferencePool, you create a new InferencePool, configured to select the pods with the `nvidia-h100-80gb` accelerator type.
 
-```yaml
-kubectl apply -f - <<EOF
----
-apiVersion: inference.networking.x-k8s.io/v1alpha2
-kind: InferenceModel
-metadata:
-  name: food-review-new
-spec:
-  criticality: 1
-  poolRef:
-    name: vllm-llama3-8b-instruct-new
-  targetModels:
-    - name: food-review-1
-      weight: 100
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: vllm-llama3-8b-instruct-new
-spec:
-  replicas: 3
-  selector:
-    matchLabels:
-      app: vllm-llama3-8b-instruct-new
-  template:
-    metadata:
-      labels:
-        app: vllm-llama3-8b-instruct-new
-    spec:
-      containers:
-        - name: vllm
-          image: "vllm/vllm-openai:latest"
-          imagePullPolicy: Always
-          command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
-          args:
-            - "--model"
-            - "meta-llama/Llama-3.1-8B-Instruct"
-            - "--tensor-parallel-size"
-            - "1"
-            - "--port"
-            - "8000"
-            - "--max-num-seq"
-            - "1024"
-            - "--compilation-config"
-            - "3"
-            - "--enable-lora"
-            - "--max-loras"
-            - "2"
-            - "--max-lora-rank"
-            - "8"
-            - "--max-cpu-loras"
-            - "12"
-          env:
-            - name: VLLM_USE_V1
-              value: "1"
-            - name: PORT
-              value: "8000"
-            - name: HUGGING_FACE_HUB_TOKEN
-              valueFrom:
-                secretKeyRef:
-                  name: hf-token
-                  key: token
-            - name: VLLM_ALLOW_RUNTIME_LORA_UPDATING
-              value: "true"
-          ports:
-            - containerPort: 8000
-              name: http
-              protocol: TCP
-          lifecycle:
-            preStop:
-              sleep:
-                seconds: 30
-          livenessProbe:
-            httpGet:
-              path: /health
-              port: http
-              scheme: HTTP
-            periodSeconds: 1
-            successThreshold: 1
-            failureThreshold: 5
-            timeoutSeconds: 1
-          readinessProbe:
-            httpGet:
-              path: /health
-              port: http
-              scheme: HTTP
-            periodSeconds: 1
-            successThreshold: 1
-            failureThreshold: 1
-            timeoutSeconds: 1
-          startupProbe:
-            failureThreshold: 600
-            initialDelaySeconds: 2
-            periodSeconds: 1
-            httpGet:
-              path: /health
-              port: http
-              scheme: HTTP
-          resources:
-            limits:
-              nvidia.com/gpu: 1
-            requests:
-              nvidia.com/gpu: 1
-          volumeMounts:
-            - mountPath: /data
-              name: data
-            - mountPath: /dev/shm
-              name: shm
-            - name: adapters
-              mountPath: "/adapters"
-      initContainers:
-        - name: lora-adapter-syncer
-          tty: true
-          stdin: true
-          image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/lora-syncer:main
-          restartPolicy: Always
-          imagePullPolicy: Always
-          env:
-            - name: DYNAMIC_LORA_ROLLOUT_CONFIG
-              value: "/config/configmap.yaml"
-          volumeMounts: # DO NOT USE subPath, dynamic configmap updates don't work on subPaths
-            - name: config-volume
-              mountPath:  /config
-      restartPolicy: Always
-      enableServiceLinks: false
-      terminationGracePeriodSeconds: 130
-      nodeSelector:
-        cloud.google.com/gke-accelerator: "nvidia-h100-80gb"
-      volumes:
-        - name: data
-          emptyDir: {}
-        - name: shm
-          emptyDir:
-            medium: Memory
-        - name: adapters
-          emptyDir: {}
-        - name: config-volume
-          configMap:
-            name: vllm-llama3-8b-instruct-adapters-new
----
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: vllm-llama3-8b-instruct-adapters-new
-data:
-  configmap.yaml: |
-    vLLMLoRAConfig:
-      name: vllm-llama3-8b-instruct-adapters-new
-      port: 8000
-      defaultBaseModel: meta-llama/Llama-3.1-8B-Instruct
-      ensureExist:
-        models:
-        - id: food-review-1
-          source: Kawon/llama3.1-food-finetune_v14_r8
----
-apiVersion: inference.networking.k8s.io/v1
-kind: InferencePool
-metadata:
-  name: vllm-llama3-8b-instruct-new
-spec:
-  targetPorts:
-    - number: 8000
-  selector:
-    app: vllm-llama3-8b-instruct-new
-  extensionRef:
-    name: vllm-llama3-8b-instruct-epp-new
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: vllm-llama3-8b-instruct-epp-new
-  namespace: default
-spec:
-  selector:
-    app: vllm-llama3-8b-instruct-epp-new
-  ports:
-    - protocol: TCP
-      port: 9002
-      targetPort: 9002
-      appProtocol: http2
-  type: ClusterIP
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: vllm-llama3-8b-instruct-epp-new
-  namespace: default
-  labels:
-    app: vllm-llama3-8b-instruct-epp-new
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: vllm-llama3-8b-instruct-epp-new
-  template:
-    metadata:
-      labels:
-        app: vllm-llama3-8b-instruct-epp-new
-    spec:
-      terminationGracePeriodSeconds: 130
-      containers:
-      - name: epp
-        image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/epp:main
-        imagePullPolicy: Always
-        args:
-        - --pool-name
-        - "vllm-llama3-8b-instruct-new"
-        - --pool-namespace
-        - "default"
-        - --v
-        - "4"
-        - --zap-encoder
-        - "json"
-        - --grpc-port
-        - "9002"
-        - --grpc-health-port
-        - "9003"
-        - --config-file
-        - "/config/default-plugins.yaml"
-        ports:
-        - containerPort: 9002
-          name: grpc
-        - containerPort: 9003
-          name: grpc-health
-        - containerPort: 9090
-          name: metrics
-        livenessProbe:
-          grpc:
-            port: 9003
-            service: inference-extension
-          initialDelaySeconds: 5
-          periodSeconds: 10
-        readinessProbe:
-          grpc:
-            port: 9003
-            service: inference-extension
-          initialDelaySeconds: 5
-          periodSeconds: 10
-        volumeMounts:
-        - name: plugins-config-volume
-          mountPath: /config
-      volumes:
-      - name: plugins-config-volume
-        configMap:
-          name: plugins-config
----
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: plugins-config
-  namespace: default
-data:
-  default-plugins.yaml: |
-    apiVersion: inference.networking.x-k8s.io/v1alpha1
-    kind: EndpointPickerConfig
-    plugins:
-    - type: queue-scorer
-    - type: kv-cache-utilization-scorer
-    - type: prefix-cache-scorer
-    schedulingProfiles:
-    - name: default
-      plugins:
-      - pluginRef: queue-scorer
-      - pluginRef: kv-cache-utilization-scorer
-      - pluginRef: prefix-cache-scorer
-EOF
-```
+Assuming the new model servers already exist, simply:
+**Create a new helm-managed InferencePool of a different name, with a new selector specified**
 
 ### Direct traffic to the new inference pool
 By configuring an **HTTPRoute**, as shown below, you can incrementally split traffic between the original `vllm-llama3-8b-instruct` and new `vllm-llama3-8b-instruct-new`.
@@ -396,14 +129,9 @@ spec:
             value: /
 ```
 
-### Delete old version of InferencePool, InferenceModel and Endpoint Picker Extension
+### Delete old version of InferencePool and Endpoint Picker Extension
 ```shell
-kubectl delete InferenceModel food-review --ignore-not-found
-kubectl delete Deployment vllm-llama3-8b-instruct --ignore-not-found
-kubectl delete ConfigMap vllm-llama3-8b-instruct-adapters --ignore-not-found
-kubectl delete InferencePool vllm-llama3-8b-instruct --ignore-not-found
-kubectl delete Deployment vllm-llama3-8b-instruct-epp --ignore-not-found
-kubectl delete Service vllm-llama3-8b-instruct-epp --ignore-not-found
+helm uninstall <old-inference-pool-name>
 ```
 
 With this, all requests should be served by the new Inference Pool.
diff --git a/site-src/guides/metrics-and-observability.md b/site-src/guides/metrics-and-observability.md
index 34b0db1..5e1f02e 100644
--- a/site-src/guides/metrics-and-observability.md
+++ b/site-src/guides/metrics-and-observability.md
@@ -32,15 +32,15 @@ This guide describes the current state of exposed metrics and how to scrape them
 
 | **Metric name**                              | **Metric Type**  | <div style="width:200px">**Description**</div>  | <div style="width:250px">**Labels**</div>                                          | **Status**  |
 |:---------------------------------------------|:-----------------|:------------------------------------------------------------------|:-----------------------------------------------------------------------------------|:------------|
-| inference_model_request_total                | Counter          | The counter of requests broken out for each model.                | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
-| inference_model_request_error_total          | Counter          | The counter of requests errors broken out for each model.         | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
-| inference_model_request_duration_seconds     | Distribution     | Distribution of response latency.                                 | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
+| inference_objective_request_total                | Counter          | The counter of requests broken out for each model.                | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
+| inference_objective_request_error_total          | Counter          | The counter of requests errors broken out for each model.         | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
+| inference_objective_request_duration_seconds     | Distribution     | Distribution of response latency.                                 | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
 | normalized_time_per_output_token_seconds     | Distribution     | Distribution of ntpot (response latency per output token)                                 | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
-| inference_model_request_sizes                | Distribution     | Distribution of request size in bytes.                            | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
-| inference_model_response_sizes               | Distribution     | Distribution of response size in bytes.                           | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
-| inference_model_input_tokens                 | Distribution     | Distribution of input token count.                                | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
-| inference_model_output_tokens                | Distribution     | Distribution of output token count.                               | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
-| inference_model_running_requests                | Gauge     | Number of running requests for each model.             | `model_name`=&lt;model-name&gt;  | ALPHA       |
+| inference_objective_request_sizes                | Distribution     | Distribution of request size in bytes.                            | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
+| inference_objective_response_sizes               | Distribution     | Distribution of response size in bytes.                           | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
+| inference_objective_input_tokens                 | Distribution     | Distribution of input token count.                                | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
+| inference_objective_output_tokens                | Distribution     | Distribution of output token count.                               | `model_name`=&lt;model-name&gt; <br> `target_model_name`=&lt;target-model-name&gt; | ALPHA       |
+| inference_objective_running_requests                | Gauge     | Number of running requests for each model.             | `model_name`=&lt;model-name&gt;  | ALPHA       |
 | inference_pool_average_kv_cache_utilization  | Gauge            | The average kv cache utilization for an inference server pool.    | `name`=&lt;inference-pool-name&gt;                                                 | ALPHA       |
 | inference_pool_average_queue_size            | Gauge            | The average number of requests pending in the model server queue. | `name`=&lt;inference-pool-name&gt;                                                 | ALPHA       |
 | inference_pool_per_pod_queue_size            | Gauge            | The total number of queue for each model server pod under the inference pool         | `model_server_pod`=&lt;model-server-pod-name&gt; <br> `name`=&lt;inference-pool-name&gt;                             | ALPHA       |
@@ -216,7 +216,7 @@ A template alert rule is available at [alert.yaml](../../tools/alerts/alert.yaml
 
 ```yaml
 alert: HighInferenceRequestLatencyP99
-expr: histogram_quantile(0.99, rate(inference_model_request_duration_seconds_bucket[5m])) > 10.0 # Adjust threshold as needed (e.g., 10.0 seconds)
+expr: histogram_quantile(0.99, rate(inference_objective_request_duration_seconds_bucket[5m])) > 10.0 # Adjust threshold as needed (e.g., 10.0 seconds)
 for: 5m
 annotations:
   title: 'High latency (P99) for model {% raw %}{{ $labels.model_name }}{% endraw %}'
@@ -229,7 +229,7 @@ labels:
 
 ```yaml
 alert: HighInferenceErrorRate
-expr: sum by (model_name) (rate(inference_model_request_error_total[5m])) / sum by (model_name) (rate(inference_model_request_total[5m])) > 0.05 # Adjust threshold as needed (e.g., 5% error rate)
+expr: sum by (model_name) (rate(inference_objective_request_error_total[5m])) / sum by (model_name) (rate(inference_objective_request_total[5m])) > 0.05 # Adjust threshold as needed (e.g., 5% error rate)
 for: 5m
 annotations:
   title: 'High error rate for model {% raw %}{{ $labels.model_name }}{% endraw %}'
diff --git a/site-src/guides/serve-multiple-genai-models.md b/site-src/guides/serve-multiple-genai-models.md
index 4eb120a..25198e8 100644
--- a/site-src/guides/serve-multiple-genai-models.md
+++ b/site-src/guides/serve-multiple-genai-models.md
@@ -1,74 +1,244 @@
 # Serve multiple generative AI models
-A company wants to deploy multiple large language models (LLMs) to serve different workloads. 
-For example, they might want to deploy a Gemma3 model for a chatbot interface and a Deepseek model for a recommendation application. 
-The company needs to ensure optimal serving performance for these LLMs.
-By using an Inference Gateway, you can deploy these LLMs on your cluster with your chosen accelerator configuration in an `InferencePool`. 
-You can then route requests based on the model name (such as "chatbot" and "recommender") and the `Criticality` property.
+
+A company wants to deploy multiple large language models (LLMs) to a cluster to serve different workloads.
+For example, they might want to deploy a Gemma3 model for a chatbot interface and a DeepSeek model for a recommendation application (or as in the example in this guide, a combination of a Llama3 model and a smaller Phi4 model).. You may choose to locate these 2 models at 2 different L7 url paths and follow the steps described in the [`Getting started`](index.md) guide for each such model as already described. However you may also need to serve multiple models located at the same L7 url path and rely on parsing information such as
+the Model name in the LLM prompt requests as defined in the OpenAI API format which is commonly used by most models. For such Model-aware routing, you can use the Body-Based Routing feature as described in this guide. 
 
 ## How
+
 The following diagram illustrates how an Inference Gateway routes requests to different models based on the model name.
-The model name is extracted by [Body-Based routing](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/pkg/bbr/README.md)
+The model name is extracted by [Body-Based routing](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/pkg/bbr/README.md) (BBR)
  from the request body to the header. The header is then matched to dispatch
  requests to different `InferencePool` (and their EPPs) instances.
-![Serving multiple generative AI models](../images/serve-mul-gen-AI-models.png)
 
-This example illustrates a conceptual example regarding how to use the `HTTPRoute` object to route based on model name like “chatbot” or “recommender” to `InferencePool`.
+### Example Model-Aware Routing using Body-Based Routing (BBR)
+
+This guide assumes you have already setup the cluster for basic model serving as described in the [`Getting started`](index.md) guide and this guide describes the additional steps needed from that point onwards in order to deploy and exercise an example of routing across multiple models.
+
+
+### Deploy Body-Based Routing Extension
+
+To enable body-based routing, you need to deploy the Body-Based Routing ExtProc server using Helm. This is a separate ExtProc server from the EndPoint Picker and when installed, is automatically inserted at the start of the gateway's ExtProc chain ahead of other EtxProc servers such as EPP.  
+
+First install this server. Depending on your Gateway provider, you can use one of the following commands:
+
+=== "GKE"
+
+    ```bash
+    helm install body-based-router \
+    --set provider.name=gke \
+    --version v1.0.0 \
+    oci://registry.k8s.io/gateway-api-inference-extension/charts/body-based-routing
+    ```
+
+=== "Istio"
+
+    ```bash
+    helm install body-based-router \
+    --set provider.name=istio \
+    --version v1.0.0 \
+    oci://registry.k8s.io/gateway-api-inference-extension/charts/body-based-routing
+    ```
+
+=== "Other"
+
+    ```bash
+    helm install body-based-router \
+    --version v1.0.0 \
+    oci://registry.k8s.io/gateway-api-inference-extension/charts/body-based-routing
+    ```
+
+Once this is installed, verify that the BBR pod is running without errors using the command `kubectl get pods`.
+
+### Serving a Second Base Model
+Next deploy the second base model that will be served from the same L7 path (which is `/`) as the `meta-llama/Llama-3.1-8B-Instruct` model already being served after following the steps from the [`Getting started`](index.md) guide. In this example the 2nd model is `microsoft/Phi-4-mini-instruct` a relatively small model ( about 3B parameters) from HuggingFace. Note that for this exercise, there need to be atleast 2 GPUs available on the system one each for the two models being served. Serve the second model via the following command. 
+
+```bash
+kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/refs/heads/main/config/manifests/bbr-example/vllm-phi4-mini.yaml
+```
+Once this is installed, and after allowing for model download and startup time which can last several minutes, verify that the pod with this 2nd LLM phi4-mini, is running without errors using the command `kubectl get pods`.
+
+### Deploy the 2nd InferencePool and Endpoint Picker Extension
+We also want to use an InferencePool and EndPoint Picker for this second model in addition to the Body Based Router in order to be able to schedule across multiple endpoints or LORA adapters within each base model. Hence we create these for our second model as follows.
+
+=== "GKE"
+
+    ```bash
+    export GATEWAY_PROVIDER=gke
+    helm install vllm-phi4-mini-instruct \
+    --set inferencePool.modelServers.matchLabels.app=phi4-mini \
+    --set provider.name=$GATEWAY_PROVIDER \
+    --version v1.0.0 \
+    oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
+    ```
+
+=== "Istio"
+
+    ```bash
+    export GATEWAY_PROVIDER=istio
+    helm install vllm-phi4-mini-instruct \
+    --set inferencePool.modelServers.matchLabels.app=phi4-mini \
+    --set provider.name=$GATEWAY_PROVIDER \
+    --version v1.0.0 \
+    oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
+    ```
+
+After executing this, verify that you see two InferencePools and two EPP pods, one per base model type, running without errors, using the CLIs `kubectl get inferencepools` and `kubectl get pods`.
+
+### Configure HTTPRoute
+
+Before configuring the httproutes for the models, we need to delete the prior httproute created for the vllm-llama3-8b-instruct model because we will alter the routing to now also match on the model name as determined by the `X-Gateway-Model-Name` http header that will get inserted by the BBR extension after parsing the Model name from the body of the LLM request message. 
+
+```bash
+kubectl delete httproute llm-route
+```
+
+Now configure new HTTPRoutes, one per each model we want to serve via BBR using the following command which configures both routes. Also examine this manifest file, to see how the `X-Gateway-Model-Name` is used for a header match in the Gateway's rules to route requests to the correct Backend based on model name. For convenience the manifest is also listed below in order to view this routing configuration.
+
+```bash
+kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/main/config/manifests/bbr-example/httproute_bbr.yaml
+```
+
 ```yaml
+---   
 apiVersion: gateway.networking.k8s.io/v1
 kind: HTTPRoute
 metadata:
-  name: routes-to-llms
+  name: llm-llama-route
 spec:
   parentRefs:
-  - name: inference-gateway
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: inference-gateway
   rules:
-  - matches:
-    - headers:
-      - type: Exact
-        #Body-Based routing(https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/pkg/bbr/README.md) is being used to copy the model name from the request body to the header.
-        name: X-Gateway-Model-Name
-        value: chatbot
-      path:
+  - backendRefs:
+    - group: inference.networking.k8s.io
+      kind: InferencePool
+      name: vllm-llama3-8b-instruct
+    matches:
+    - path:
         type: PathPrefix
         value: /
-    backendRefs:
-    - name: gemma3
+      headers:
+        - type: Exact
+          #Body-Based routing(https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/pkg/bbr/README.md) is being used to copy the model name from the request body to the header.
+          name: X-Gateway-Model-Name # (1)!
+          value: 'meta-llama/Llama-3.1-8B-Instruct'
+    timeouts:
+      request: 300s
+---   
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: llm-phi4-route
+spec:
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: inference-gateway
+  rules:
+  - backendRefs:
+    - group: inference.networking.k8s.io
       kind: InferencePool
-  - matches:
-    - headers:
-      - type: Exact
-        #Body-Based routing(https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/pkg/bbr/README.md) is being used to copy the model name from the request body to the header.
-        name: X-Gateway-Model-Name
-        value: recommender
-      path:
+      name: vllm-phi4-mini-instruct
+    matches:
+    - path:
         type: PathPrefix
         value: /
-    backendRefs:
-    - name: deepseek-r1
-      kind: InferencePool     
+      headers:
+        - type: Exact
+          #Body-Based routing(https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/pkg/bbr/README.md) is being used to copy the model name from the request body to the header.
+          name: X-Gateway-Model-Name
+          value: 'microsoft/Phi-4-mini-instruct'
+    timeouts:
+      request: 300s
+---   
 ```
 
-## Try it out
+Before testing the setup, confirm that the HTTPRoute status conditions include `Accepted=True` and `ResolvedRefs=True` for both routes using the following commands. 
 
-1. Get the gateway IP:
 ```bash
-IP=$(kubectl get gateway/inference-gateway -o jsonpath='{.status.addresses[0].value}'); PORT=80
+kubectl get httproute llm-llama-route -o yaml
 ```
-2. Send a few requests to model "chatbot" as follows:
-```bash
-curl -i ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -d '{
-"model": "chatbot",
-"prompt": "What is the color of the sky",
-"max_tokens": 100,
-"temperature": 0
-}'
-```
-3. Send a few requests to model "recommender" as follows:
+
 ```bash
-curl -i ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -d '{
-"model": "recommender",
-"prompt": "Give me restaurant recommendations in Paris",
-"max_tokens": 100,
-"temperature": 0
-}'
+kubectl get httproute llm-phi4-route -o yaml
 ```
+
+## Try it out
+
+1. Get the gateway IP:
+    ```bash
+    IP=$(kubectl get gateway/inference-gateway -o jsonpath='{.status.addresses[0].value}'); PORT=80
+    ```
+
+=== "Chat Completions API"
+
+    1. Send a few requests to Llama model as follows:
+        ```bash
+        curl -X POST -i ${IP}:${PORT}/v1/chat/completions \
+          -H "Content-Type: application/json" \
+          -d '{
+                "model": "meta-llama/Llama-3.1-8B-Instruct",
+                "max_tokens": 100,
+                "temperature": 0,
+                "messages": [
+                  {
+                    "role": "developer",
+                    "content": "You are a helpful assistant."
+                  },
+                  {
+                    "role": "user",
+                    "content": "Linux is said to be an open source kernel because "
+                  }
+                ]
+          }'
+        ```
+
+    2. Send a few requests to the Phi4 as follows:
+        ```bash
+        curl -X POST -i ${IP}:${PORT}/v1/chat/completions \
+          -H "Content-Type: application/json" \
+          -d '{
+                "model": "microsoft/Phi-4-mini-instruct",
+                "max_tokens": 100,
+                "temperature": 0,
+                "messages": [
+                  {
+                    "role": "developer",
+                    "content": "You are a helpful assistant."
+                  },
+                  {
+                    "role": "user",
+                    "content": "2+2 is "
+                  }
+                ]
+          }'
+        ```
+
+=== "Completions API"
+
+    1. Send a few requests to Llama model as follows:
+        ```bash
+        curl -X POST -i ${IP}:${PORT}/v1/completions \
+          -H "Content-Type: application/json" \
+          -d '{
+                "model": "meta-llama/Llama-3.1-8B-Instruct",
+                "prompt": "Linux is said to be an open source kernel because ",
+                "max_tokens": 100,
+                "temperature": 0
+          }'
+        ```
+
+    2. Send a few requests to the Phi4 as follows:
+        ```bash
+        curl -X POST -i ${IP}:${PORT}/v1/completions \
+          -H "Content-Type: application/json" \
+          -d '{
+                "model": "microsoft/Phi-4-mini-instruct",
+                "prompt": "2+2 is ",
+                "max_tokens": 20,
+                "temperature": 0
+          }'
+        ```
+
diff --git a/site-src/guides/serve-multiple-lora-adapters.md b/site-src/guides/serve-multiple-lora-adapters.md
deleted file mode 100644
index 59cfe72..0000000
--- a/site-src/guides/serve-multiple-lora-adapters.md
+++ /dev/null
@@ -1,98 +0,0 @@
-# Serve LoRA adapters on a shared pool
-A company wants to serve LLMs for document analysis and focuses on audiences in multiple languages, such as English and Spanish.
-They have a fine-tuned LoRA adapter for each language, but need to efficiently use their GPU and TPU capacity.
-You can use an Inference Gateway to deploy dynamic LoRA fine-tuned adapters for each language (for example, `english-bot` and `spanish-bot`) on a common base model and accelerator.
-This lets you reduce the number of required accelerators by densely packing multiple models in a shared pool.
-
-## How
-The following diagram illustrates how Inference Gateway serves multiple LoRA adapters on a shared pool.
-![Serving LoRA adapters on a shared pool](../images/serve-LoRA-adapters.png)
-This example illustrates how you can densely serve multiple LoRA adapters with distinct workload performance objectives on a common InferencePool.
-```yaml
-apiVersion: gateway.networking.x-k8s.io/v1alpha1
-kind: InferencePool
-metadata:
-  name: gemma3
-spec:
-  selector:
-    pool: gemma3
-```
-Let us say we have a couple of LoRA adapters named “english-bot” and “spanish-bot” for the Gemma3 base model.
-You can create an `InferenceModel` resource and associate these LoRA adapters to the relevant InferencePool resource.  
-In this case, we associate these LoRA adapters to the gemma3 InferencePool resource created above.
-
-```yaml
-apiVersion: inference.networking.x-k8s.io/v1alpha2
-kind: InferenceModel
-metadata:
-  name: english-bot
-spec:
-  criticality: 1
-  poolRef:
-    name: gemma3
-        
----
-apiVersion: inference.networking.x-k8s.io/v1alpha2
-kind: InferenceModel
-metadata:
-  name: spanish-bot
-spec:
-  criticality: 2
-  poolRef:
-    name: gemma3
-    
-```
-Now, you can route your requests from the gateway using the `HTTPRoute` object.
-```yaml
-apiVersion: gateway.networking.k8s.io/v1
-kind: Gateway
-metadata:
-  name: inference-gateway
-spec:
-  listeners:
-  - protocol: HTTP
-    port: 80
-    name: http
-
----
-kind: HTTPRoute
-apiVersion: gateway.networking.k8s.io/v1
-metadata:
-  name: routes-to-llms
-spec:
-  parentRefs:
-    - name: inference-gateway
-  rules:
-  - matches:
-      path:
-        type: PathPrefix
-        value: /
-    backendRefs:
-    - name: gemma3
-      kind: InferencePool
-```
-
-## Try it out
-
-1. Get the gateway IP:
-```bash
-IP=$(kubectl get gateway/inference-gateway -o jsonpath='{.status.addresses[0].value}'); PORT=80
-```
-2. Send a few requests to model "english-bot" as follows:
-```bash
-curl -i ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -d '{
-"model": "english-bot",
-"prompt": "What is the color of the sky",
-"max_tokens": 100,
-"temperature": 0
-}'
-```
-3. Send a few requests to model "spanish-bot" as follows:
-```bash
-curl -i ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -d '{
-"model": "spanish-bot",
-"prompt": "¿De qué color es...?",
-"max_tokens": 100,
-"temperature": 0
-}'
-```
\ No newline at end of file
diff --git a/site-src/guides/troubleshooting.md b/site-src/guides/troubleshooting.md
new file mode 100644
index 0000000..1f08619
--- /dev/null
+++ b/site-src/guides/troubleshooting.md
@@ -0,0 +1,91 @@
+# Troubleshooting Guide
+
+This guide provides troubleshooting steps and solutions for common issues encountered with the Gateway API inference extension.
+
+## 400 Bad Request
+
+### `model not found in request body` or `prompt not found in request`
+If the OpenAI API endpoint you're using isn't working as expected, the issue might be related to the request body format. The endpoint picker (EPP) assumes that if a request is a POST, its body must contain the `model` field and the `prompt` (or `messages`) field. This is because the gateway currently assumes the requests are for Large Language Models (LLMs).
+
+**Solution**: Make sure your request body contains the missing field.
+
+## 404 Not Found
+This is a default gateway error, meaning the request never reached a backend service. This usually means that there is no HTTPRoute configured to match the request path (e.g. /v1/completions). The gateway doesn't know where to send the traffic.
+
+**Solution**: Ensure you have an HTTPRoute resource deployed that specifies the correct host, path, and backendRef to your InferencePool.
+
+## 429 Too Many Requests
+### `system saturated, sheddable request dropped`
+This error indicates that the entire inference pool has exceeded its saturation thresholds. This means the system is under heavy load and is shedding low priority requests. To address this, check the following:
+
+* gateway-api-inference-extension version:
+    * **v0.5.1 and earlier**: Verify you're using an `InferenceModel` and that its `criticality` is set to `Critical`. This ensures requests are queued on the model servers instead of being dropped.
+    * **v1.0.0 and later**: Ensure the `InferenceObjective` you're using has a `priority` greater than or equal to 0. A negative priority can cause requests to be dropped.
+
+* Pool Thresholds: Check the defined pool [thresholds](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/f36111cab0ed5a309d1eafade896d4f37ab623a6/pkg/epp/saturationdetector/config.go#L41) to understand the saturation limits. Currently, we use three main metrics to assess the system's load:
+    * `DefaultQueueDepthThreshold`: This is the maximum number of requests waiting in the queue for a backend. The default value is 5. If the queue for a model server exceeds this number, the saturation detector may consider the system under pressure. To override this, set the `SD_QUEUE_DEPTH_THRESHOLD` environment variable.
+    * `DefaultKVCacheUtilThreshold`: This is the maximum utilization of the Key-Value (KV) cache on the model server, expressed as a decimal from 0.0 to 1.0. The default is 0.8, or 80%. The KV cache stores attention keys and values to speed up inference for subsequent tokens. When its utilization exceeds this threshold, it's an indication that the model server is nearing its memory capacity and may be becoming saturated. To override this, set the `SD_KV_CACHE_UTIL_THRESHOLD` environment variable.
+    * `DefaultMetricsStalenessThreshold`: This defines the maximum age of metrics data before it's considered outdated. The default is 200 milliseconds. The saturation detector needs up-to-date metrics to make accurate decisions about system load. If the metrics are older than this threshold, the detector won't use them. This value is tied to how often metrics are refreshed, and setting it slightly higher ensures that there's always fresh data available. To override this, set the `SD_METRICS_STALENESS_THRESHOLD` environment variable.
+
+## 500 Internal Server Error
+### `fault filter abort`
+This internal error suggests a misconfiguration in the gateway's backend routing. Your HTTPRoute is configured to point to an InferencePool that does not exist or cannot be found by the gateway. The gateway recognizes the route but fails when trying to send traffic to the non-existent backend.
+
+**Solution**: Verify that the backendRef in your HTTPRoute correctly names an InferencePool resource that is deployed and accessible in the same namespace. If you wish to route to an InferencePool in a different namespace, you can create a `ReferenceGrant` like below:
+
+```
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: ReferenceGrant
+metadata:
+  name: ref-grant
+  namespace: ns2
+spec:
+  from:
+    - group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      namespace: ns1
+  to:
+    - group: inference.networking.k8s.io
+      kind: InferencePool
+      name: my-inference-pool
+```
+
+## 502 Bad Gateway or 503 Service Unavailable
+### `upstream connect error or disconnect/reset ...`
+The gateway can return an error when it cannot connect to its backends. This error indicates that the gateway successfully identified the correct model server pod but failed to establish a connection to it. This is likely caused by the port number specified in the InferencePool's configuration doesn't match the port your model server is listening on. The gateway tries to connect to the wrong port and is refused.
+
+**Solution**: Verify the port specified in your InferencePool matches the port number exposed by your model server container, and update your InferencePool accordingly.
+
+## 503 Service Unavailable
+### `no healthy upstream`
+This error indicates that the HTTPRoute and InferencePool are correctly configured, but there are no healthy pods in the pool to route traffic to. This can happen if the pods are crashing, still starting up, or failing their health checks.
+
+**Solution**: Check the status of your model server pods. Investigate the pod logs for any startup errors or health check failures. Ensure your model server is running and listening on the correct port and that any configured healthchecks / readiness probes are succeeding.
+
+## The endpoint picker (EPP) Crashlooping
+When EPP is crashlooping, check the logs of your EPP pod. Some common errors include:
+
+### `failed to list <InferencePool or InferenceObjective or Pod>: … is forbidden`
+The EPP needs to watch the InferencePool, InferenceObjectives and Pods that belong to them. This constant watching and reconciliation allows the EPP to maintain an up-to-date view of the environment, enabling it to make dynamic decisions. This particular error indicates that the service account used by the EPP doesn't have the necessary permissions to list the resources it’s watching.
+
+**Solution**: Create or update the RBAC configuration to grant the [required permissions](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/a3f25c07231a47945d52518e979aa7ee386907d3/config/charts/inferencepool/templates/rbac.yaml#L41) to the EPP service account.
+
+### `Pool is not initialized, skipping refreshing metrics`
+This error indicates that the Inference Pool pods are not initialized. 
+
+**Solution**: Check the EPP start up argument `--pool-name` has the correct InferencePool name specified and the InferencePool exists.
+
+## Unexpected Routing Behaviors
+The EPP's core function is to intelligently route requests to the most optimal model server pod in a pool. It uses a score-based algorithm that considers several metrics (such as queue depth, KV cache utilization, etc.) to choose the best pod for each request. 
+
+For unexpected routing behaviors: 
+
+* Verify the expected metrics are being emitted from the model server. Some model servers aren't fully compatible with the default expected metrics, vLLM is generally the most up-to-date in this regard. See [Support Model Servers](https://gateway-api-inference-extension.sigs.k8s.io/implementations/model-servers/).
+* Check your [plugins](https://gateway-api-inference-extension.sigs.k8s.io/guides/epp-configuration/config-text/) configuration, especially the weights of the scorer plugins. If weight is omitted, a default weight of 1 will be used.
+
+## Poor Performance under High Concurrency
+For more information, check out [EPP scale testing](https://docs.google.com/document/d/1TDD_wvuTO5hhm1Byl8K7TZkNnn8sVQ1ZrkZM_u0gJvw/edit?tab=t.0#heading=h.mtff4cnithxf).
+
+When performance degrades under high load (for example high-latency tail or significantly lower-than-expected successful QPS) with underutilized resources, the issue may be related to excessive logging in the endpoint picker (EPP). Higher verbosity levels (e.g., `--v=2` or greater) generate a large volume of logs. This floods the log buffer and standard output, leading to heavy writelock contention. In extreme cases, this can cause the kubelet to kill the pod due to health check timeouts, leading to a restart cycle. 
+
+**Solution**: Ensure log level for the EPP is set to `--v=1`.
diff --git a/site-src/images/inference-overview.svg b/site-src/images/inference-overview.svg
index a82c09e..8524ebb 100644
--- a/site-src/images/inference-overview.svg
+++ b/site-src/images/inference-overview.svg
@@ -1 +1 @@
-<svg version="1.1" viewBox="0.0 0.0 757.3700787401575 171.03412073490813" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><clipPath id="p.0"><path d="m0 0l757.37006 0l0 171.03412l-757.37006 0l0 -171.03412z" clip-rule="nonzero"/></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l757.37006 0l0 171.03412l-757.37006 0z" fill-rule="evenodd"/><path fill="#ead1dc" d="m492.2756 27.767786l0 0c0 -2.450531 1.9865417 -4.4370766 4.4370728 -4.4370766l244.4802 0c1.1767578 0 2.305359 0.4674759 3.1374512 1.2995892c0.8320923 0.83211327 1.2996216 1.960701 1.2996216 3.1374874l0 44.38569c0 2.450531 -1.9865723 4.4370804 -4.4370728 4.4370804l-244.4802 0c-2.450531 0 -4.4370728 -1.9865494 -4.4370728 -4.4370804z" fill-rule="evenodd"/><path stroke="#d5a6bd" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m492.2756 27.767786l0 0c0 -2.450531 1.9865417 -4.4370766 4.4370728 -4.4370766l244.4802 0c1.1767578 0 2.305359 0.4674759 3.1374512 1.2995892c0.8320923 0.83211327 1.2996216 1.960701 1.2996216 3.1374874l0 44.38569c0 2.450531 -1.9865723 4.4370804 -4.4370728 4.4370804l-244.4802 0c-2.450531 0 -4.4370728 -1.9865494 -4.4370728 -4.4370804z" fill-rule="evenodd"/><path fill="#d9ead3" d="m253.18898 18.972511l0 0c0 -2.450531 1.9865417 -4.4370785 4.437088 -4.4370785l172.79514 0c1.1767578 0 2.305359 0.46747684 3.1374817 1.2995901c0.8320923 0.8321142 1.2995911 1.960702 1.2995911 3.1374884l0 44.385685c0 2.4505348 -1.9865417 4.4370766 -4.4370728 4.4370766l-172.79514 0c-2.4505463 0 -4.437088 -1.9865417 -4.437088 -4.4370766z" fill-rule="evenodd"/><path stroke="#b6d7a8" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m253.18898 18.972511l0 0c0 -2.450531 1.9865417 -4.4370785 4.437088 -4.4370785l172.79514 0c1.1767578 0 2.305359 0.46747684 3.1374817 1.2995901c0.8320923 0.8321142 1.2995911 1.960702 1.2995911 3.1374884l0 44.385685c0 2.4505348 -1.9865417 4.4370766 -4.4370728 4.4370766l-172.79514 0c-2.4505463 0 -4.437088 -1.9865417 -4.437088 -4.4370766z" fill-rule="evenodd"/><path fill="#274e13" d="m264.8948 38.305355l0 -12.406252l2.34375 0l0 12.406252l-2.34375 0zm1.296875 -5.234375l0 -2.218752l7.296875 0l0 2.218752l-7.296875 0zm6.25 5.234375l0 -12.406252l2.34375 0l0 12.406252l-2.34375 0zm7.5920715 0l0 -11.234377l2.34375 0l0 11.234377l-2.34375 0zm-3.46875 -10.187502l0 -2.21875l9.28125 0l0 2.21875l-9.28125 0zm13.934998 10.187502l0 -11.234377l2.34375 0l0 11.234377l-2.34375 0zm-3.46875 -10.187502l0 -2.21875l9.28125 0l0 2.21875l-9.28125 0zm11.064178 10.187502l0 -12.406252l4.359375 0q1.203125 0 2.15625 0.5q0.953125 0.484375 1.515625 1.375q0.5625 0.875 0.5625 2.046875q0 1.15625 -0.5625 2.046875q-0.5625 0.8906269 -1.515625 1.3906269q-0.953125 0.484375 -2.15625 0.484375l-3.0625 0l0 -2.218752l3.140625 0q0.609375 0 1.015625 -0.234375q0.421875 -0.25 0.625 -0.640625q0.203125 -0.390625 0.203125 -0.828125q0 -0.453125 -0.203125 -0.828125q-0.203125 -0.390625 -0.625 -0.625q-0.40625 -0.25 -1.015625 -0.25l-2.09375 0l0 10.187502l-2.34375 0zm10.535461 0l0 -12.406252l4.515625 0q1.25 0 2.171875 0.5q0.9375 0.5 1.453125 1.390625q0.515625 0.875 0.515625 2.03125q0 0.84375 -0.359375 1.546875q-0.34375 0.7031269 -0.96875 1.2187519q-0.609375 0.5 -1.4375 0.78125q-0.8125 0.28125 -1.75 0.28125l-2.84375 0l0 -2.156252l3.203125 0q0.546875 0 0.9375 -0.21875q0.40625 -0.234375 0.640625 -0.625q0.234375 -0.390625 0.234375 -0.875q0 -0.4375 -0.203125 -0.828125q-0.203125 -0.390625 -0.609375 -0.625q-0.390625 -0.25 -0.96875 -0.25l-2.1875 0l0 10.234377l-2.34375 0zm2.734375 -5.625l2.734375 0l3.84375 5.484375l0 0.140625l-2.671875 0l-3.90625 -5.625zm12.244476 5.90625q-1.375 0 -2.453125 -0.609375q-1.0625 -0.625 -1.65625 -1.6875q-0.59375 -1.0625 -0.59375 -2.40625q0 -1.328125 0.59375 -2.390627q0.59375 -1.078125 1.65625 -1.6875q1.078125 -0.609375 2.453125 -0.609375q1.390625 0 2.4375 0.625q1.0625 0.625 1.65625 1.6875q0.609375 1.0468769 0.609375 2.375002q0 1.34375 -0.609375 2.40625q-0.59375 1.0625 -1.65625 1.6875q-1.046875 0.609375 -2.4375 0.609375zm0 -2.125q0.671875 0 1.203125 -0.296875q0.546875 -0.296875 0.890625 -0.875q0.34375 -0.59375 0.34375 -1.40625q0 -0.8125 -0.34375 -1.375q-0.34375 -0.5781269 -0.890625 -0.8906269q-0.53125 -0.3125 -1.171875 -0.3125q-0.671875 0 -1.234375 0.3125q-0.5625 0.3125 -0.90625 0.8906269q-0.328125 0.5625 -0.328125 1.375q0 0.8125 0.328125 1.40625q0.34375 0.578125 0.90625 0.875q0.5625 0.296875 1.203125 0.296875zm9.59082 2.125q-1.625 0 -2.453125 -1.0q-0.8125 -1.015625 -0.8125 -2.75l0 -5.375002l2.28125 0l0 5.093752q0 0.90625 0.4375 1.421875q0.4375 0.515625 1.140625 0.515625q0.671875 0 1.140625 -0.34375q0.46875 -0.34375 0.71875 -0.90625q0.25 -0.578125 0.25 -1.265625l0 -4.515627l2.265625 0l0 8.843752l-2.125 0l0 -1.109375l-0.140625 0q-0.265625 0.421875 -0.6875 0.734375q-0.40625 0.3125 -0.921875 0.484375q-0.5 0.171875 -1.09375 0.171875zm6.5010986 -7.171877l0 -1.953125l1.625 0l0 1.953125l-1.625 0zm4.46875 7.031252q-1.375 0 -2.15625 -0.78125q-0.78125 -0.796875 -0.78125 -2.1875l0 -8.500002l2.28125 0l0 8.093752q0 0.640625 0.25 0.9375q0.265625 0.296875 0.859375 0.296875q0.265625 0 0.5 -0.078125q0.25 -0.078125 0.625 -0.296875l0 2.21875q-0.390625 0.140625 -0.78125 0.21875q-0.390625 0.078125 -0.796875 0.078125zm-0.75 -7.031252l0 -1.953125l2.25 0l0 1.953125l-2.25 0zm7.835907 7.171877q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328127q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.0156269 0.5 2.250002q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125019 -0.4375 -0.5781269q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.9531269q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625z" fill-rule="nonzero"/><path fill="#274e13" d="m270.7698 53.026608q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm7.808075 3.671875l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm9.370575 3.171875q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm8.04245 0.09375l-1.25 0l0 -4.59375q0 -0.828125 -0.3125 -1.234375q-0.3125 -0.40625 -0.890625 -0.40625q-0.25 0 -0.46875 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.28125 0.28125 -0.640625 0.71875l0 4.765625l-1.25 0l0 -10.109375l1.25 0l0 2.921875l-0.046875 1.140625q0.296875 -0.359375 0.578125 -0.59375q0.28125 -0.25 0.5625 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.078125 0 1.65625 0.65625q0.59375 0.65625 0.59375 1.96875l0 4.6875zm5.16745 -7.3125q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.006775 -8.046875l-4.90625 11.640625l-1.1875 0l4.90625 -11.640625l1.1875 0zm7.870575 9.84375q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.72995 -3.390625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.1987 3.59375l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0737 -3.71875q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm5.6362 -5.421875l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm11.683075 5.125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm9.0737 4.0625q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm4.714325 -6.0625l-2.125 0l0 -1.03125l3.390625 0l0 6.15625l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -5.125zm0.4375 -4.046875q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.21875 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.078125 0.171875 -0.21875 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.203125 0 -0.390625 -0.078125q-0.171875 -0.078125 -0.3125 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.140625 -0.140625 0.3125 -0.21875q0.1875 -0.078125 0.390625 -0.078125zm11.433075 6.546875q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm3.0737 -3.59375l1.109375 0l0.046875 1.15625q0.328125 -0.359375 0.609375 -0.609375q0.296875 -0.25 0.578125 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.109375 0 1.671875 0.65625q0.578125 0.65625 0.578125 1.96875l0 4.6875l-1.25 0l0 -4.59375q0 -0.84375 -0.3125 -1.234375q-0.3125 -0.40625 -0.9375 -0.40625q-0.234375 0 -0.453125 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.265625 0.28125 -0.609375 0.71875l0 4.765625l-1.25 0l0 -7.1875zm13.745575 5.234375q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m204.56693 41.165356l48.62993 0" fill-rule="evenodd"/><path stroke="#b7b7b7" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m216.56693 41.165356l36.62993 0" fill-rule="evenodd"/><path fill="#b7b7b7" stroke="#b7b7b7" stroke-width="2.0" stroke-linecap="butt" d="m216.56693 37.86189l-9.076187 3.3034668l9.076187 3.303463z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m434.85828 41.165356l48.629913 0" fill-rule="evenodd"/><path stroke="#b7b7b7" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m434.85828 41.165356l36.629913 0" fill-rule="evenodd"/><path fill="#b7b7b7" stroke="#b7b7b7" stroke-width="2.0" stroke-linecap="butt" d="m471.4882 44.46882l9.076202 -3.303463l-9.076202 -3.3034668z" fill-rule="evenodd"/><path fill="#ead1dc" d="m483.48032 18.972511l0 0c0 -2.450531 1.9865417 -4.4370785 4.4370728 -4.4370785l244.4802 0c1.1767578 0 2.305359 0.46747684 3.1374512 1.2995901c0.8321533 0.8321142 1.2996216 1.960702 1.2996216 3.1374884l0 44.385685c0 2.4505348 -1.9865723 4.4370766 -4.4370728 4.4370766l-244.4802 0c-2.450531 0 -4.4370728 -1.9865417 -4.4370728 -4.4370766z" fill-rule="evenodd"/><path stroke="#d5a6bd" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m483.48032 18.972511l0 0c0 -2.450531 1.9865417 -4.4370785 4.4370728 -4.4370785l244.4802 0c1.1767578 0 2.305359 0.46747684 3.1374512 1.2995901c0.8321533 0.8321142 1.2996216 1.960702 1.2996216 3.1374884l0 44.385685c0 2.4505348 -1.9865723 4.4370766 -4.4370728 4.4370766l-244.4802 0c-2.450531 0 -4.4370728 -1.9865417 -4.4370728 -4.4370766z" fill-rule="evenodd"/><path fill="#4c1130" d="m495.18613 38.305355l0 -12.406252l2.34375 0l0 12.406252l-2.34375 0zm4.8339233 0l0 -8.843752l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625002l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125019q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.8906269q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm9.428589 -6.890627l0 -1.953125l1.65625 0l0 1.953125l-1.65625 0zm1.578125 6.890627l0 -9.328127q0 -0.984375 0.40625 -1.703125q0.40625 -0.734375 1.1406555 -1.125q0.734375 -0.390625 1.734375 -0.390625q0.359375 0 0.71875 0.0625q0.359375 0.046875 0.6875 0.125l0 2.21875q-0.296875 -0.140625 -0.578125 -0.203125q-0.265625 -0.078125 -0.546875 -0.078125q-0.59375 0 -0.953125 0.34375q-0.34375 0.34375 -0.34375 0.953125l0 9.125002l-2.2656555 0zm2.1719055 -6.890627l0 -1.953125l2.265625 0l0 1.953125l-2.265625 0zm7.406128 7.171877q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328127q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.0156269 0.5 2.250002q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125019 -0.4375 -0.5781269q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.9531269q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.843752l2.125 0l0 1.1875l0.140625 0q0.234375 -0.421875 0.59375 -0.734375q0.375 -0.328125 0.875 -0.515625q0.515625 -0.1875 1.078125 -0.1875q0.34375 0 0.625 0.046875q0.28125 0.046875 0.484375 0.140625l0 2.265625q-0.359375 -0.140625 -0.71875 -0.234375q-0.359375 -0.09375 -0.75 -0.09375q-0.671875 0 -1.171875 0.34375q-0.5 0.3281269 -0.765625 0.9218769q-0.25 0.578125 -0.25 1.296875l0 4.40625l-2.265625 0zm11.08905 0.28125q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328127q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.0156269 0.5 2.250002q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125019 -0.4375 -0.5781269q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.9531269q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.843752l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625002l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125019q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.8906269q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm14.501099 0.28125q-1.34375 0 -2.40625 -0.59375q-1.046875 -0.609375 -1.640625 -1.671875q-0.59375 -1.0625 -0.59375 -2.4375q0 -1.359375 0.59375 -2.421877q0.59375 -1.0625 1.640625 -1.65625q1.0625 -0.609375 2.40625 -0.609375q1.46875 0 2.53125 0.625q1.0625 0.625 1.53125 1.796875l-2.09375 0.8593769q-0.265625 -0.5937519 -0.78125 -0.8750019q-0.5 -0.296875 -1.1875 -0.296875q-0.671875 0 -1.21875 0.328125q-0.53125 0.3125 -0.84375 0.8906269q-0.3125 0.5625 -0.3125 1.359375q0 0.796875 0.3125 1.390625q0.3125 0.578125 0.84375 0.90625q0.546875 0.3125 1.21875 0.3125q0.765625 0 1.265625 -0.34375q0.5 -0.34375 0.8125 -0.921875l2.03125 0.890625q-0.515625 1.109375 -1.578125 1.796875q-1.0625 0.671875 -2.53125 0.671875zm9.635986 0q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328127q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.0156269 0.5 2.250002q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125019 -0.4375 -0.5781269q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.9531269q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm6.291443 -0.28125l0 -12.406252l4.359375 0q1.203125 0 2.15625 0.5q0.953125 0.484375 1.515625 1.375q0.5625 0.875 0.5625 2.046875q0 1.15625 -0.5625 2.046875q-0.5625 0.8906269 -1.515625 1.3906269q-0.953125 0.484375 -2.15625 0.484375l-3.0625 0l0 -2.218752l3.140625 0q0.609375 0 1.015625 -0.234375q0.421875 -0.25 0.625 -0.640625q0.203125 -0.390625 0.203125 -0.828125q0 -0.453125 -0.203125 -0.828125q-0.203125 -0.390625 -0.625 -0.625q-0.40625 -0.25 -1.015625 -0.25l-2.09375 0l0 10.187502l-2.34375 0zm14.008362 0.28125q-1.375 0 -2.453125 -0.609375q-1.0625 -0.625 -1.65625 -1.6875q-0.59375 -1.0625 -0.59375 -2.40625q0 -1.328125 0.59375 -2.390627q0.59375 -1.078125 1.65625 -1.6875q1.078125 -0.609375 2.453125 -0.609375q1.390625 0 2.4375 0.625q1.0625 0.625 1.65625 1.6875q0.609375 1.0468769 0.609375 2.375002q0 1.34375 -0.609375 2.40625q-0.59375 1.0625 -1.65625 1.6875q-1.046875 0.609375 -2.4375 0.609375zm0 -2.125q0.671875 0 1.203125 -0.296875q0.546875 -0.296875 0.890625 -0.875q0.34375 -0.59375 0.34375 -1.40625q0 -0.8125 -0.34375 -1.375q-0.34375 -0.5781269 -0.890625 -0.8906269q-0.53125 -0.3125 -1.171875 -0.3125q-0.671875 0 -1.234375 0.3125q-0.5625 0.3125 -0.90625 0.8906269q-0.328125 0.5625 -0.328125 1.375q0 0.8125 0.328125 1.40625q0.34375 0.578125 0.90625 0.875q0.5625 0.296875 1.203125 0.296875zm10.622131 2.125q-1.375 0 -2.453125 -0.609375q-1.0625 -0.625 -1.65625 -1.6875q-0.59375 -1.0625 -0.59375 -2.40625q0 -1.328125 0.59375 -2.390627q0.59375 -1.078125 1.65625 -1.6875q1.078125 -0.609375 2.453125 -0.609375q1.390625 0 2.4375 0.625q1.0625 0.625 1.65625 1.6875q0.609375 1.0468769 0.609375 2.375002q0 1.34375 -0.609375 2.40625q-0.59375 1.0625 -1.65625 1.6875q-1.046875 0.609375 -2.4375 0.609375zm0 -2.125q0.671875 0 1.203125 -0.296875q0.546875 -0.296875 0.890625 -0.875q0.34375 -0.59375 0.34375 -1.40625q0 -0.8125 -0.34375 -1.375q-0.34375 -0.5781269 -0.890625 -0.8906269q-0.53125 -0.3125 -1.171875 -0.3125q-0.671875 0 -1.234375 0.3125q-0.5625 0.3125 -0.90625 0.8906269q-0.328125 0.5625 -0.328125 1.375q0 0.8125 0.328125 1.40625q0.34375 0.578125 0.90625 0.875q0.5625 0.296875 1.203125 0.296875zm6.4033203 1.84375l0 -12.406252l2.265625 0l0 12.406252l-2.265625 0z" fill-rule="nonzero"/><path fill="#4c1130" d="m500.608 54.792233q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.4487 -2.015625q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm5.7299805 -4.9375l-2.1250305 0l0 -1.015625l3.3906555 0l0 9.078125l2.125 0l0 1.03125l-5.7500305 0l0 -1.03125l2.3594055 0l0 -8.0625zm11.683044 5.125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.870605 3.890625q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.261169 0.171875q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm8.526855 -3.5625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm3.3705444 -3.59375l1.140625 0l0.03125 1.328125q0.640625 -0.765625 1.25 -1.109375q0.625 -0.34375 1.25 -0.34375q1.125 0 1.703125 0.71875q0.578125 0.71875 0.53125 2.15625l-1.265625 0q0.03125 -0.953125 -0.265625 -1.375q-0.296875 -0.421875 -0.875 -0.421875q-0.25 0 -0.515625 0.09375q-0.25 0.078125 -0.515625 0.28125q-0.265625 0.1875 -0.5625 0.5q-0.296875 0.3125 -0.640625 0.75l0 4.609375l-1.265625 0l0 -7.1875zm10.651855 -0.125q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm18.506775 5.0l-0.53125 0q-1.375 0 -2.0625 -0.65625q-0.671875 -0.640625 -0.671875 -1.953125l0 -2.46875q0 -0.34375 -0.078125 -0.625q-0.078125 -0.28125 -0.28125 -0.46875q-0.1875 -0.1875 -0.515625 -0.28125q-0.328125 -0.109375 -0.8125 -0.109375l-0.3125 0l0 -0.984375l0.3125 0q0.515625 0 0.84375 -0.078125q0.328125 -0.09375 0.515625 -0.265625q0.1875 -0.1875 0.25 -0.453125q0.078125 -0.28125 0.078125 -0.640625l0 -1.703125q0 -0.59375 0.140625 -1.078125q0.15625 -0.484375 0.46875 -0.828125q0.328125 -0.34375 0.84375 -0.515625q0.53125 -0.1875 1.28125 -0.1875l0.53125 0l0 1.0l-0.421875 0q-1.65625 0 -1.65625 1.609375l0 1.671875q0 1.734375 -1.515625 1.96875q1.515625 0.140625 1.515625 1.953125l0 2.453125q0 1.640625 1.65625 1.640625l0.421875 0l0 1.0zm8.917419 -6.65625q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm9.44873 0.015625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm9.339294 -0.0625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm5.5268555 -5.5l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm8.495544 1.78125q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.36615 -1.65625q0 0.890625 -0.25 1.59375q-0.234375 0.703125 -0.703125 1.203125q-0.453125 0.484375 -1.109375 0.75q-0.640625 0.25 -1.453125 0.25q-0.640625 0 -1.3125 -0.109375q-0.65625 -0.125 -1.3125 -0.390625l0 -9.6875l1.25 0l0 2.78125l-0.0625 1.328125q0.546875 -0.71875 1.15625 -1.015625q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.359375 0.140625 0.734375 0.234375q0.390625 0.078125 0.734375 0.078125q0.421875 0 0.8125 -0.125q0.390625 -0.140625 0.6875 -0.453125q0.296875 -0.328125 0.46875 -0.859375q0.1875 -0.53125 0.1875 -1.3125zm7.8081055 3.671875l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm9.261169 1.3125q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.44873 -2.015625q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.308044 0.84375l-4.28125 0l0 -1.171875l4.28125 0l0 1.171875zm8.151855 3.3125l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.198669 -3.65625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm2.7143555 0.15625q0 -0.921875 0.25 -1.625q0.25 -0.71875 0.703125 -1.203125q0.46875 -0.5 1.109375 -0.75q0.65625 -0.25 1.453125 -0.25q0.34375 0 0.671875 0.046875q0.328125 0.03125 0.65625 0.125l0 -3.015625l1.25 0l0 10.109375l-1.109375 0l-0.046875 -1.359375q-0.515625 0.765625 -1.125 1.125q-0.609375 0.359375 -1.328125 0.359375q-0.609375 0 -1.078125 -0.25q-0.46875 -0.265625 -0.78125 -0.734375q-0.3125 -0.46875 -0.46875 -1.125q-0.15625 -0.65625 -0.15625 -1.453125zm1.265625 -0.078125q0 1.296875 0.375 1.9375q0.390625 0.640625 1.09375 0.640625q0.484375 0 1.0 -0.421875q0.53125 -0.421875 1.109375 -1.25l0 -3.34375q-0.3125 -0.140625 -0.6875 -0.203125q-0.359375 -0.078125 -0.734375 -0.078125q-1.015625 0 -1.59375 0.65625q-0.5625 0.65625 -0.5625 2.0625zm13.229919 -0.453125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm5.7299805 -4.9375l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm6.1049194 -1.265625l0.53125 0q1.375 0 2.046875 0.65625q0.671875 0.640625 0.671875 1.953125l0 1.65625q0 0.34375 0.078125 0.625q0.078125 0.265625 0.28125 0.46875q0.203125 0.1875 0.53125 0.296875q0.328125 0.09375 0.8125 0.09375l0.3125 0l0 0.984375l-0.3125 0q-0.515625 0 -0.859375 0.09375q-0.328125 0.078125 -0.515625 0.265625q-0.1875 0.171875 -0.265625 0.4375q-0.0625 0.265625 -0.0625 0.640625l0 2.515625q0 0.59375 -0.140625 1.078125q-0.140625 0.484375 -0.46875 0.8125q-0.3125 0.34375 -0.84375 0.53125q-0.515625 0.1875 -1.265625 0.1875l-0.53125 0l0 -1.0l0.421875 0q1.65625 0 1.65625 -1.609375l0 -2.484375q0 -1.75 1.515625 -1.953125q-1.53125 -0.171875 -1.53125 -1.96875l0 -1.640625q0 -1.640625 -1.640625 -1.640625l-0.421875 0l0 -1.0z" fill-rule="nonzero"/><path fill="#c9daf8" d="m2.5485563 9.969208l0 0c0 -3.7881055 3.070866 -6.8589716 6.8589716 -6.8589716l190.84898 0c1.819107 0 3.5637207 0.72263956 4.8500214 2.0089464c1.2863159 1.2863064 2.0089417 3.0309124 2.0089417 4.850025l0 68.61276c0 3.7881088 -3.0708618 6.8589783 -6.858963 6.8589783l-190.84898 0l0 0c-3.7881055 0 -6.8589716 -3.0708694 -6.8589716 -6.8589783z" fill-rule="evenodd"/><path stroke="#a4c2f4" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m2.5485563 9.969208l0 0c0 -3.7881055 3.070866 -6.8589716 6.8589716 -6.8589716l190.84898 0c1.819107 0 3.5637207 0.72263956 4.8500214 2.0089464c1.2863159 1.2863064 2.0089417 3.0309124 2.0089417 4.850025l0 68.61276c0 3.7881088 -3.0708618 6.8589783 -6.858963 6.8589783l-190.84898 0l0 0c-3.7881055 0 -6.8589716 -3.0708694 -6.8589716 -6.8589783z" fill-rule="evenodd"/><path fill="#1c4587" d="m20.885605 32.69684q-1.328125 0 -2.515625 -0.484375q-1.1875 -0.484375 -2.109375 -1.34375q-0.90624905 -0.875 -1.421874 -2.0625q-0.5 -1.1875 -0.5 -2.59375q0 -1.40625 0.5 -2.59375q0.515625 -1.1875 1.421874 -2.046875q0.90625 -0.875 2.09375 -1.359375q1.1875 -0.484375 2.53125 -0.484375q1.484375 0 2.6875 0.53125q1.203125 0.515625 2.046875 1.4375l-1.609375 1.5625q-0.40625 -0.421875 -0.875 -0.703125q-0.46875 -0.296875 -1.03125 -0.453125q-0.546875 -0.15625 -1.234375 -0.15625q-0.84375 0 -1.609375 0.3125q-0.75 0.296875 -1.328125 0.859375q-0.578125 0.5625 -0.90625 1.34375q-0.328125 0.78125 -0.328125 1.75q0 0.96875 0.328125 1.75q0.328125 0.78125 0.90625 1.34375q0.578125 0.5625 1.34375 0.875q0.765625 0.296875 1.625 0.296875q0.875 0 1.546875 -0.234375q0.671875 -0.25 1.140625 -0.65625q0.484375 -0.421875 0.765625 -0.9375q0.296875 -0.515625 0.375 -1.046875l-3.890625 0l0 -2.0l6.078125 0q0.046875 0.171875 0.078125 0.53125q0.046875 0.34375 0.046875 0.5625l0 0l0 0l0 0q0 1.375 -0.46875 2.484375q-0.453125 1.109375 -1.28125 1.90625q-0.8125 0.78125 -1.953125 1.203125q-1.125 0.40625 -2.453125 0.40625zm10.485352 0q-0.9375 0 -1.65625 -0.375q-0.71875 -0.375 -1.140625 -1.046875q-0.40625 -0.671875 -0.40625 -1.5625q0 -0.921875 0.46875 -1.578125q0.484375 -0.65625 1.28125 -1.015625q0.8125 -0.375 1.796875 -0.375q0.546875 0 0.984375 0.0625q0.4375 0.0625 0.78125 0.15625q0.34375 0.078125 0.578125 0.1875l0 -0.390625q0 -0.703125 -0.546875 -1.15625q-0.53125 -0.46875 -1.46875 -0.46875q-0.625 0 -1.203125 0.296875q-0.578125 0.28125 -0.953125 0.75l-1.46875 -1.140625q0.4375 -0.5625 1.0 -0.953125q0.578125 -0.390625 1.265625 -0.578125q0.703125 -0.203125 1.46875 -0.203125q2.03125 0 3.078125 0.9375q1.0625 0.921875 1.0625 2.734375l0 5.4375l-2.234375 0l0 -0.90625l-0.140625 0q-0.25 0.3125 -0.609375 0.59375q-0.359375 0.265625 -0.84375 0.421875q-0.484375 0.171875 -1.09375 0.171875zm0.53125 -1.765625q0.703125 0 1.171875 -0.296875q0.484375 -0.3125 0.734375 -0.796875q0.25 -0.484375 0.25 -1.03125q-0.390625 -0.1875 -0.875 -0.296875q-0.484375 -0.109375 -0.984375 -0.109375q-1.0 0 -1.390625 0.390625q-0.375 0.375 -0.375 0.921875q0 0.515625 0.375 0.875q0.375 0.34375 1.09375 0.34375zm5.537445 -5.40625l0 -1.953125l1.625 0l0 1.953125l-1.625 0zm4.46875 7.03125q-1.375 0 -2.15625 -0.78125q-0.78125 -0.796875 -0.78125 -2.1875l0 -8.5l2.28125 0l0 8.09375q0 0.640625 0.25 0.9375q0.265625 0.296875 0.859375 0.296875q0.265625 0 0.5 -0.078125q0.25 -0.078125 0.625 -0.296875l0 2.21875q-0.390625 0.140625 -0.78125 0.21875q-0.390625 0.078125 -0.796875 0.078125zm-0.75 -7.03125l0 -1.953125l2.25 0l0 1.953125l-2.25 0zm7.8359222 7.171875q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm7.791443 -0.28125l-2.796875 -8.84375l2.546875 0l1.515625 5.734375l0.125 0l1.765625 -5.734375l2.328125 0l1.765625 5.734375l0.125 0l1.515625 -5.734375l2.515625 0l-2.828125 8.84375l-2.4375 0l-1.796875 -5.71875l-0.125 0l-1.78125 5.71875l-2.4375 0zm15.149826 0.28125q-0.9375 0 -1.65625 -0.375q-0.71875 -0.375 -1.140625 -1.046875q-0.40625 -0.671875 -0.40625 -1.5625q0 -0.921875 0.46875 -1.578125q0.484375 -0.65625 1.28125 -1.015625q0.8125 -0.375 1.796875 -0.375q0.546875 0 0.984375 0.0625q0.4375 0.0625 0.78125 0.15625q0.34375 0.078125 0.578125 0.1875l0 -0.390625q0 -0.703125 -0.546875 -1.15625q-0.53125 -0.46875 -1.46875 -0.46875q-0.625 0 -1.203125 0.296875q-0.578125 0.28125 -0.953125 0.75l-1.46875 -1.140625q0.4375 -0.5625 1.0 -0.953125q0.578125 -0.390625 1.265625 -0.578125q0.703125 -0.203125 1.46875 -0.203125q2.03125 0 3.078125 0.9375q1.0625 0.921875 1.0625 2.734375l0 5.4375l-2.234375 0l0 -0.90625l-0.140625 0q-0.25 0.3125 -0.609375 0.59375q-0.359375 0.265625 -0.84375 0.421875q-0.484375 0.171875 -1.09375 0.171875zm0.53125 -1.765625q0.703125 0 1.171875 -0.296875q0.484375 -0.3125 0.734375 -0.796875q0.25 -0.484375 0.25 -1.03125q-0.390625 -0.1875 -0.875 -0.296875q-0.484375 -0.109375 -0.984375 -0.109375q-1.0 0 -1.390625 0.390625q-0.375 0.375 -0.375 0.921875q0 0.515625 0.375 0.875q0.375 0.34375 1.09375 0.34375zm9.702225 4.828125q-0.046875 0.125 -0.09375 0.21875q-0.03125 0.09375 -0.078125 0.1875l-2.4375 0q0.0625 -0.140625 0.265625 -0.59375q0.203125 -0.4375 0.34375 -0.75q0.09375 -0.203125 0.234375 -0.53125q0.140625 -0.328125 0.28125 -0.65625q0.15625 -0.3125 0.25 -0.484375l1.328125 -2.96875l0.46875 -1.109375l2.203125 -5.5l2.53125 0l-4.5625 10.5q-0.1875 0.453125 -0.34375 0.78125q-0.140625 0.328125 -0.234375 0.546875q-0.078125 0.21875 -0.15625 0.359375zm-0.59375 -3.484375l-3.859375 -8.703125l2.59375 0l2.28125 5.5l0.265625 0l-1.28125 3.203125z" fill-rule="nonzero"/><path fill="#1c4587" d="m20.479355 50.855587l-1.25 0l0 -4.59375q0 -0.828125 -0.3125 -1.234375q-0.3125 -0.40625 -0.890625 -0.40625q-0.25 0 -0.46875 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.28125 0.28125 -0.64062405 0.71875l0 4.765625l-1.25 0l0 -10.109375l1.25 0l0 2.921875l-0.046875 1.140625q0.29687405 -0.359375 0.57812405 -0.59375q0.28125 -0.25 0.5625 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.078125 0 1.65625 0.65625q0.59375 0.65625 0.59375 1.96875l0 4.6875zm8.54245 -3.65625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.7612 1.640625q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.16745 1.859375q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm2.2612 -7.09375l1.109375 0l0.046875 1.15625q0.328125 -0.359375 0.609375 -0.609375q0.296875 -0.25 0.578125 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.109375 0 1.671875 0.65625q0.578125 0.65625 0.578125 1.96875l0 4.6875l-1.25 0l0 -4.59375q0 -0.84375 -0.3125 -1.234375q-0.3125 -0.40625 -0.9375 -0.40625q-0.234375 0 -0.453125 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.265625 0.28125 -0.609375 0.71875l0 4.765625l-1.25 0l0 -7.1875zm12.683075 7.1875l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm8.6987 3.265625l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0112 -3.96875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm6.16745 -3.15625q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.30365 -1.90625q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm9.7612 4.15625l-1.65625 0l-1.9375 -2.734375l-1.921875 2.734375l-1.609375 0l2.78125 -3.609375l-2.65625 -3.578125l1.59375 0l1.890625 2.765625l1.859375 -2.765625l1.53125 0l-2.6875 3.609375l2.8125 3.578125zm6.1987 0l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm8.6987 3.265625l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0737 -3.71875q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm5.6362 -5.421875l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm11.683075 5.125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm6.10495 1.90625q0.25 0 0.46875 0.09375q0.21875 0.09375 0.375 0.265625q0.15625 0.15625 0.25 0.375q0.09375 0.21875 0.09375 0.46875q0 0.234375 -0.09375 0.453125q-0.09375 0.21875 -0.25 0.375q-0.15625 0.15625 -0.375 0.25q-0.21875 0.09375 -0.46875 0.09375q-0.25 0 -0.46875 -0.09375q-0.203125 -0.09375 -0.375 -0.25q-0.15625 -0.15625 -0.25 -0.375q-0.09375 -0.21875 -0.09375 -0.453125q0 -0.25 0.09375 -0.46875q0.09375 -0.21875 0.25 -0.375q0.171875 -0.171875 0.375 -0.265625q0.21875 -0.09375 0.46875 -0.09375zm10.8237 1.984375q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.72995 -3.390625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.1987 3.59375l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0z" fill-rule="nonzero"/><path fill="#1c4587" d="m20.83873 65.13684q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.68749905 -0.125l0 3.015625l-1.25 0l0 -10.125004l1.109375 0l0.078125 1.203125q0.54687405 -0.734375 1.156249 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.6562538 0.15625 1.4687538zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.4687538 -0.265625 -0.7968788q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.60937405 0.7031288l0 3.484375q0.34374905 0.140625 0.71874905 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm9.4487 0.015625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.5312538q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875038 0.234375 1.5625038zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5000038 -0.421875 -0.8281288q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.8437538q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm3.370575 -3.5937538l1.140625 0l0.03125 1.328125q0.640625 -0.765625 1.25 -1.109375q0.625 -0.34375 1.25 -0.34375q1.125 0 1.703125 0.71875q0.578125 0.71875 0.53125 2.1562538l-1.265625 0q0.03125 -0.9531288 -0.265625 -1.3750038q-0.296875 -0.421875 -0.875 -0.421875q-0.25 0 -0.515625 0.09375q-0.25 0.078125 -0.515625 0.28125q-0.265625 0.1875 -0.5625 0.5q-0.296875 0.3125 -0.640625 0.7500038l0 4.609375l-1.265625 0l0 -7.187504zm13.558075 7.093754q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.7500038l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.6562538q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm5.151825 -7.218754q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.250004q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.756775 0l-1.59375 0l0 2.0625l-1.265625 0l0 -2.0625l-4.5 0l0 -1.09375l3.984375 -6.203129l1.78125 0l0 6.203129l1.59375 0l0 1.09375zm-2.859375 -6.093754l-3.265625 5.000004l3.265625 0l0 -5.000004zm10.91745 6.093754l-1.59375 0l0 2.0625l-1.265625 0l0 -2.0625l-4.5 0l0 -1.09375l3.984375 -6.203129l1.78125 0l0 6.203129l1.59375 0l0 1.09375zm-2.859375 -6.093754l-3.265625 5.000004l3.265625 0l0 -5.000004zm10.276825 5.312504q0 0.625 -0.25 1.171875q-0.25 0.53125 -0.75 0.9375q-0.5 0.390625 -1.265625 0.625q-0.75 0.234375 -1.765625 0.234375q-0.546875 0 -1.0 -0.03125q-0.4375 -0.03125 -0.828125 -0.09375l0 -1.109375q0.453125 0.078125 0.9375 0.125q0.5 0.03125 1.015625 0.03125q0.703125 0 1.1875 -0.125q0.5 -0.125 0.8125 -0.359375q0.328125 -0.234375 0.46875 -0.5625q0.140625 -0.34375 0.140625 -0.765625q0 -0.390625 -0.171875 -0.671875q-0.171875 -0.296875 -0.484375 -0.484375q-0.3125 -0.1875 -0.75 -0.28125q-0.421875 -0.109375 -0.9375 -0.109375l-1.078125 0l0 -1.0156288l1.09375 0q0.421875 0 0.765625 -0.109375q0.34375 -0.109375 0.59375 -0.3125q0.25 -0.21875 0.375 -0.515625q0.140625 -0.3125 0.140625 -0.703125q0 -0.75 -0.46875 -1.09375q-0.453125 -0.34375 -1.34375 -0.34375q-0.46875 0 -0.96875 0.09375q-0.5 0.09375 -1.078125 0.28125l0 -1.09375q0.25 -0.078125 0.515625 -0.140625q0.28125 -0.078125 0.546875 -0.125q0.28125 -0.046875 0.546875 -0.0625q0.28125 -0.03125 0.53125 -0.03125q0.75 0 1.3125 0.171875q0.5625 0.15625 0.9375 0.453125q0.390625 0.296875 0.578125 0.734375q0.1875 0.421875 0.1875 0.96875q0 0.796875 -0.40625 1.34375q-0.40625 0.53125 -1.125 0.859375q0.359375 0.0625 0.71875 0.23437881q0.359375 0.171875 0.640625 0.4375q0.28125 0.265625 0.453125 0.640625q0.171875 0.359375 0.171875 0.796875z" fill-rule="nonzero"/><path fill="#c9daf8" d="m0 6.858971l0 0c0 -3.788105 3.070866 -6.858971 6.858971 -6.858971l190.84898 0c1.819107 0 3.5637207 0.72263956 4.8500214 2.0089462c1.2863007 1.2863066 2.0089417 3.0309126 2.0089417 4.850025l0 68.61277c0 3.7881012 -3.0708618 6.8589706 -6.858963 6.8589706l-190.84898 0l0 0c-3.788105 0 -6.858971 -3.0708694 -6.858971 -6.8589706z" fill-rule="evenodd"/><path stroke="#a4c2f4" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m0 6.858971l0 0c0 -3.788105 3.070866 -6.858971 6.858971 -6.858971l190.84898 0c1.819107 0 3.5637207 0.72263956 4.8500214 2.0089462c1.2863007 1.2863066 2.0089417 3.0309126 2.0089417 4.850025l0 68.61277c0 3.7881012 -3.0708618 6.8589706 -6.858963 6.8589706l-190.84898 0l0 0c-3.788105 0 -6.858971 -3.0708694 -6.858971 -6.8589706z" fill-rule="evenodd"/><path fill="#1c4587" d="m18.33705 29.586603q-1.328125 0 -2.515625 -0.484375q-1.1875 -0.484375 -2.109375 -1.34375q-0.90625 -0.875 -1.421875 -2.0625q-0.5 -1.1875 -0.5 -2.59375q0 -1.40625 0.5 -2.59375q0.515625 -1.1875 1.421875 -2.046875q0.90625 -0.875 2.09375 -1.359375q1.1875 -0.484375 2.53125 -0.484375q1.484375 0 2.6875 0.53125q1.203125 0.515625 2.046875 1.4375l-1.609375 1.5625q-0.40625 -0.421875 -0.875 -0.703125q-0.46875 -0.296875 -1.03125 -0.453125q-0.546875 -0.15625 -1.234375 -0.15625q-0.84375 0 -1.609375 0.3125q-0.75 0.296875 -1.328125 0.859375q-0.578125 0.5625 -0.90625 1.34375q-0.328125 0.78125 -0.328125 1.75q0 0.96875 0.328125 1.75q0.328125 0.78125 0.90625 1.34375q0.578125 0.5625 1.34375 0.875q0.765625 0.296875 1.625 0.296875q0.875 0 1.546875 -0.234375q0.671875 -0.25 1.140625 -0.65625q0.484375 -0.421875 0.765625 -0.9375q0.296875 -0.515625 0.375 -1.046875l-3.890625 0l0 -2.0l6.078125 0q0.046875 0.171875 0.078125 0.53125q0.046875 0.34375 0.046875 0.5625l0 0l0 0l0 0q0 1.375 -0.46875 2.484375q-0.453125 1.109375 -1.28125 1.90625q-0.8125 0.78125 -1.953125 1.203125q-1.125 0.40625 -2.453125 0.40625zm10.485352 0q-0.9375 0 -1.65625 -0.375q-0.71875 -0.375 -1.140625 -1.046875q-0.40625 -0.671875 -0.40625 -1.5625q0 -0.921875 0.46875 -1.578125q0.484375 -0.65625 1.28125 -1.015625q0.8125 -0.375 1.796875 -0.375q0.546875 0 0.984375 0.0625q0.4375 0.0625 0.78125 0.15625q0.34375 0.078125 0.578125 0.1875l0 -0.390625q0 -0.703125 -0.546875 -1.15625q-0.53125 -0.46875 -1.46875 -0.46875q-0.625 0 -1.203125 0.296875q-0.578125 0.28125 -0.953125 0.75l-1.46875 -1.140625q0.4375 -0.5625 1.0 -0.953125q0.578125 -0.390625 1.265625 -0.578125q0.703125 -0.203125 1.46875 -0.203125q2.03125 0 3.078123 0.9375q1.0625 0.921875 1.0625 2.734375l0 5.4375l-2.234373 0l0 -0.90625l-0.140625 0q-0.25 0.3125 -0.609375 0.59375q-0.359375 0.265625 -0.84375 0.421875q-0.484375 0.171875 -1.09375 0.171875zm0.53125 -1.765625q0.703125 0 1.171875 -0.296875q0.484375 -0.3125 0.734375 -0.796875q0.25 -0.484375 0.25 -1.03125q-0.390625 -0.1875 -0.875 -0.296875q-0.484375 -0.109375 -0.984375 -0.109375q-1.0 0 -1.390625 0.390625q-0.375 0.375 -0.375 0.921875q0 0.515625 0.375 0.875q0.375 0.34375 1.09375 0.34375zm5.537443 -5.40625l0 -1.953125l1.625 0l0 1.953125l-1.625 0zm4.46875 7.03125q-1.375 0 -2.15625 -0.78125q-0.78125 -0.796875 -0.78125 -2.1875l0 -8.5l2.28125 0l0 8.09375q0 0.640625 0.25 0.9375q0.265625 0.296875 0.859375 0.296875q0.265625 0 0.5 -0.078125q0.25 -0.078125 0.625 -0.296875l0 2.21875q-0.390625 0.140625 -0.78125 0.21875q-0.390625 0.078125 -0.796875 0.078125zm-0.75 -7.03125l0 -1.953125l2.25 0l0 1.953125l-2.25 0zm7.8359222 7.171875q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm7.791443 -0.28125l-2.796875 -8.84375l2.546875 0l1.515625 5.734375l0.125 0l1.765625 -5.734375l2.328125 0l1.765625 5.734375l0.125 0l1.515625 -5.734375l2.5156288 0l-2.8281288 8.84375l-2.4375 0l-1.796875 -5.71875l-0.125 0l-1.78125 5.71875l-2.4375 0zm15.14983 0.28125q-0.9375 0 -1.65625 -0.375q-0.71875 -0.375 -1.140625 -1.046875q-0.40625 -0.671875 -0.40625 -1.5625q0 -0.921875 0.46875 -1.578125q0.484375 -0.65625 1.28125 -1.015625q0.8125 -0.375 1.796875 -0.375q0.546875 0 0.984375 0.0625q0.4375 0.0625 0.78125 0.15625q0.34375 0.078125 0.578125 0.1875l0 -0.390625q0 -0.703125 -0.546875 -1.15625q-0.53125 -0.46875 -1.46875 -0.46875q-0.625 0 -1.203125 0.296875q-0.578125 0.28125 -0.953125 0.75l-1.46875 -1.140625q0.4375 -0.5625 1.0 -0.953125q0.578125 -0.390625 1.265625 -0.578125q0.703125 -0.203125 1.46875 -0.203125q2.03125 0 3.078125 0.9375q1.0625 0.921875 1.0625 2.734375l0 5.4375l-2.234375 0l0 -0.90625l-0.140625 0q-0.25 0.3125 -0.609375 0.59375q-0.359375 0.265625 -0.84375 0.421875q-0.484375 0.171875 -1.09375 0.171875zm0.53125 -1.765625q0.703125 0 1.171875 -0.296875q0.484375 -0.3125 0.734375 -0.796875q0.25 -0.484375 0.25 -1.03125q-0.390625 -0.1875 -0.875 -0.296875q-0.484375 -0.109375 -0.984375 -0.109375q-1.0 0 -1.390625 0.390625q-0.375 0.375 -0.375 0.921875q0 0.515625 0.375 0.875q0.375 0.34375 1.09375 0.34375zm9.702225 4.828123q-0.046875 0.125 -0.09375 0.21875q-0.03125 0.09375 -0.078125 0.1875l-2.4375 0q0.0625 -0.140625 0.265625 -0.59375q0.203125 -0.4375 0.34375 -0.7499981q0.09375 -0.203125 0.234375 -0.53125q0.140625 -0.328125 0.28125 -0.65625q0.15625 -0.3125 0.25 -0.484375l1.328125 -2.96875l0.46875 -1.109375l2.203125 -5.5l2.53125 0l-4.5625 10.5q-0.1875 0.453125 -0.34375 0.78125q-0.140625 0.3281231 -0.234375 0.5468731q-0.078125 0.21875 -0.15625 0.359375zm-0.59375 -3.484373l-3.859375 -8.703125l2.59375 0l2.28125 5.5l0.265625 0l-1.28125 3.203125z" fill-rule="nonzero"/><path fill="#1c4587" d="m17.9308 47.74535l-1.25 0l0 -4.59375q0 -0.828125 -0.3125 -1.234375q-0.3125 -0.40625 -0.890625 -0.40625q-0.25 0 -0.46875 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.28125 0.28125 -0.640625 0.71875l0 4.765625l-1.25 0l0 -10.109375l1.25 0l0 2.921875l-0.046875 1.140625q0.296875 -0.359375 0.578125 -0.59375q0.28125 -0.25 0.5625 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.078125 0 1.65625 0.65625q0.59375 0.65625 0.59375 1.96875l0 4.6875zm8.54245 -3.65625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.761198 1.640625q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6874981 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3124981 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.5468731 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9374981 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.5312481 -0.078125 -0.9062481 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.6406231 0.1875 1.0624981 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.16745 1.859375q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm2.2612 -7.09375l1.109375 0l0.046875 1.15625q0.328125 -0.359375 0.609375 -0.609375q0.296875 -0.25 0.578125 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.109375 0 1.671875 0.65625q0.578125 0.65625 0.578125 1.96875l0 4.6875l-1.25 0l0 -4.59375q0 -0.84375 -0.3125 -1.234375q-0.3125 -0.40625 -0.9375 -0.40625q-0.234375 0 -0.453125 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.265625 0.28125 -0.609375 0.71875l0 4.765625l-1.25 0l0 -7.1875zm12.683075 7.1875l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm8.698704 3.265625l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.3906288 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.3281288 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0112 -3.96875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm6.16745 -3.15625q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.30365 -1.90625q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm9.7612 4.15625l-1.65625 0l-1.9375 -2.734375l-1.921875 2.734375l-1.609375 0l2.78125 -3.609375l-2.65625 -3.578125l1.59375 0l1.890625 2.765625l1.859375 -2.765625l1.53125 0l-2.6875 3.609375l2.8125 3.578125zm6.1987 0l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm8.6987 3.265625l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0737 -3.71875q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm5.6362 -5.421875l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm11.683075 5.125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm6.10495 1.90625q0.25 0 0.46875 0.09375q0.21875 0.09375 0.375 0.265625q0.15625 0.15625 0.25 0.375q0.09375 0.21875 0.09375 0.46875q0 0.234375 -0.09375 0.453125q-0.09375 0.21875 -0.25 0.375q-0.15625 0.15625 -0.375 0.25q-0.21875 0.09375 -0.46875 0.09375q-0.25 0 -0.46875 -0.09375q-0.203125 -0.09375 -0.375 -0.25q-0.15625 -0.15625 -0.25 -0.375q-0.09375 -0.21875 -0.09375 -0.453125q0 -0.25 0.09375 -0.46875q0.09375 -0.21875 0.25 -0.375q0.171875 -0.171875 0.375 -0.265625q0.21875 -0.09375 0.46875 -0.09375zm10.8237 1.984375q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.72995 -3.390625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.1987 3.59375l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0z" fill-rule="nonzero"/><path fill="#1c4587" d="m18.290174 62.0266q0 0.953125 -0.265625 1.671875q-0.265625 0.7187538 -0.75 1.1875038q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125004l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.4843788q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875038 0.578125 -2.0625038zm9.4487 0.015625q0 0.84375 -0.25 1.546875q-0.234375 0.6875038 -0.671875 1.1875038q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.1562538q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.8281288q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.3750038 0.375 -0.8593788q0.125 -0.484375 0.125 -1.015625zm3.370575 -3.59375l1.140625 0l0.03125 1.328125q0.640625 -0.765625 1.25 -1.109375q0.625 -0.34375 1.2499981 -0.34375q1.125 0 1.703125 0.71875q0.578125 0.71875 0.53125 2.15625l-1.265625 0q0.03125 -0.953125 -0.265625 -1.375q-0.296875 -0.421875 -0.875 -0.421875q-0.2499981 0 -0.5156231 0.09375q-0.25 0.078125 -0.515625 0.28125q-0.265625 0.1875 -0.5625 0.5q-0.296875 0.3125 -0.640625 0.75l0 4.609379l-1.265625 0l0 -7.187504zm13.558073 7.093754q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.8750038l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.7656288 0.40625 1.1562538q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm5.151825 -7.218754q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.23437881q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625381 0.34375 -0.23437881q0.203125 -0.09375 0.4375 -0.09375zm19.756779 0l-1.59375 0l0 2.0625038l-1.265625 0l0 -2.0625038l-4.500004 0l0 -1.09375l3.984375 -6.203125l1.7812538 0l0 6.203125l1.59375 0l0 1.09375zm-2.859375 -6.09375l-3.2656288 5.0l3.2656288 0l0 -5.0zm10.91745 6.09375l-1.59375 0l0 2.0625038l-1.265625 0l0 -2.0625038l-4.5 0l0 -1.09375l3.984375 -6.203125l1.78125 0l0 6.203125l1.59375 0l0 1.09375zm-2.859375 -6.09375l-3.265625 5.0l3.265625 0l0 -5.0zm10.276825 5.3125q0 0.625 -0.25 1.1718788q-0.25 0.53125 -0.75 0.9375q-0.5 0.390625 -1.265625 0.625q-0.75 0.234375 -1.765625 0.234375q-0.546875 0 -1.0 -0.03125q-0.4375 -0.03125 -0.828125 -0.09375l0 -1.109375q0.453125 0.078125 0.9375 0.125q0.5 0.03125 1.015625 0.03125q0.703125 0 1.1875 -0.125q0.5 -0.125 0.8125 -0.359375q0.328125 -0.234375 0.46875 -0.5625038q0.140625 -0.34375 0.140625 -0.765625q0 -0.390625 -0.171875 -0.671875q-0.171875 -0.296875 -0.484375 -0.484375q-0.3125 -0.1875 -0.75 -0.28125q-0.421875 -0.109375 -0.9375 -0.109375l-1.078125 0l0 -1.015625l1.09375 0q0.421875 0 0.765625 -0.109375q0.34375 -0.109375 0.59375 -0.3125q0.25 -0.21875 0.375 -0.515625q0.140625 -0.3125 0.140625 -0.703125q0 -0.75 -0.46875 -1.09375q-0.453125 -0.34375 -1.34375 -0.34375q-0.46875 0 -0.96875 0.09375q-0.5 0.09375 -1.078125 0.28125l0 -1.09375q0.25 -0.078125 0.515625 -0.140625q0.28125 -0.078125 0.546875 -0.125q0.28125 -0.046875 0.546875 -0.0625q0.28125 -0.03125 0.53125 -0.03125q0.75 0 1.3125 0.171875q0.5625 0.15625 0.9375 0.453125q0.390625 0.296875 0.578125 0.734375q0.1875 0.421875 0.1875 0.96875q0 0.796875 -0.40625 1.34375q-0.40625 0.53125 -1.125 0.859375q0.359375 0.0625 0.71875 0.234375q0.359375 0.171875 0.640625 0.4375q0.28125 0.265625 0.453125 0.640625q0.171875 0.359375 0.171875 0.796875z" fill-rule="nonzero"/><path fill="#d9d2e9" d="m519.3228 109.33209l0 0c0 -2.450531 1.9865723 -4.4370804 4.4370728 -4.4370804l172.79517 0c1.1767578 0 2.305359 0.4674759 3.1375122 1.2995911c0.8320923 0.8321152 1.2995605 1.960701 1.2995605 3.1374893l0 44.38568c0 2.450531 -1.9865723 4.437088 -4.4370728 4.437088l-172.79517 0c-2.4505005 0 -4.4370728 -1.986557 -4.4370728 -4.437088z" fill-rule="evenodd"/><path stroke="#b4a7d6" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m519.3228 109.33209l0 0c0 -2.450531 1.9865723 -4.4370804 4.4370728 -4.4370804l172.79517 0c1.1767578 0 2.305359 0.4674759 3.1375122 1.2995911c0.8320923 0.8321152 1.2995605 1.960701 1.2995605 3.1374893l0 44.38568c0 2.450531 -1.9865723 4.437088 -4.4370728 4.437088l-172.79517 0c-2.4505005 0 -4.4370728 -1.986557 -4.4370728 -4.437088z" fill-rule="evenodd"/><path fill="#20124d" d="m531.0287 128.66493l0 -12.40625l2.34375 0l0 12.40625l-2.34375 0zm4.8339233 0l0 -8.84375l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.890625q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm9.428589 -6.890625l0 -1.953125l1.65625 0l0 1.953125l-1.65625 0zm1.578125 6.890625l0 -9.328125q0 -0.984375 0.40625 -1.703125q0.40625 -0.734375 1.140625 -1.125q0.734375 -0.390625 1.734375 -0.390625q0.359375 0 0.71875 0.0625q0.359375 0.046875 0.6875 0.125l0 2.21875q-0.296875 -0.140625 -0.578125 -0.203125q-0.265625 -0.078125 -0.546875 -0.078125q-0.59375 0 -0.953125 0.34375q-0.34375 0.34375 -0.34375 0.953125l0 9.125l-2.265625 0zm2.171875 -6.890625l0 -1.953125l2.265625 0l0 1.953125l-2.265625 0zm7.406128 7.171875q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.84375l2.125 0l0 1.1875l0.140625 0q0.234375 -0.421875 0.59375 -0.734375q0.375 -0.328125 0.875 -0.515625q0.515625 -0.1875 1.078125 -0.1875q0.34375 0 0.625 0.046875q0.28125 0.046875 0.484375 0.140625l0 2.265625q-0.359375 -0.140625 -0.71875 -0.234375q-0.359375 -0.09375 -0.75 -0.09375q-0.671875 0 -1.171875 0.34375q-0.5 0.328125 -0.765625 0.921875q-0.25 0.578125 -0.25 1.296875l0 4.40625l-2.265625 0zm11.08905 0.28125q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.84375l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.890625q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm14.501099 0.28125q-1.34375 0 -2.40625 -0.59375q-1.046875 -0.609375 -1.640625 -1.671875q-0.59375 -1.0625 -0.59375 -2.4375q0 -1.359375 0.59375 -2.421875q0.59375 -1.0625 1.640625 -1.65625q1.0625 -0.609375 2.40625 -0.609375q1.46875 0 2.53125 0.625q1.0625 0.625 1.53125 1.796875l-2.09375 0.859375q-0.265625 -0.59375 -0.78125 -0.875q-0.5 -0.296875 -1.1875 -0.296875q-0.671875 0 -1.21875 0.328125q-0.53125 0.3125 -0.84375 0.890625q-0.3125 0.5625 -0.3125 1.359375q0 0.796875 0.3125 1.390625q0.3125 0.578125 0.84375 0.90625q0.546875 0.3125 1.21875 0.3125q0.765625 0 1.265625 -0.34375q0.5 -0.34375 0.8125 -0.921875l2.03125 0.890625q-0.515625 1.109375 -1.578125 1.796875q-1.0625 0.671875 -2.53125 0.671875zm9.635986 0q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm6.291443 -0.28125l0 -12.40625l3.015625 0l3.296875 8.71875l0.125 0l3.296875 -8.71875l3.03125 0l0 12.40625l-2.3125 0l0 -6.109375l0.125 -2.0625l-0.125 0l-3.15625 8.171875l-1.828125 0l-3.171875 -8.171875l-0.140625 0l0.140625 2.0625l0 6.109375l-2.296875 0zm19.484192 0.28125q-1.375 0 -2.453125 -0.609375q-1.0625 -0.625 -1.65625 -1.6875q-0.59375 -1.0625 -0.59375 -2.40625q0 -1.328125 0.59375 -2.390625q0.59375 -1.078125 1.65625 -1.6875q1.078125 -0.609375 2.453125 -0.609375q1.390625 0 2.4375 0.625q1.0625 0.625 1.65625 1.6875q0.609375 1.046875 0.609375 2.375q0 1.34375 -0.609375 2.40625q-0.59375 1.0625 -1.65625 1.6875q-1.046875 0.609375 -2.4375 0.609375zm0 -2.125q0.671875 0 1.203125 -0.296875q0.546875 -0.296875 0.890625 -0.875q0.34375 -0.59375 0.34375 -1.40625q0 -0.8125 -0.34375 -1.375q-0.34375 -0.578125 -0.890625 -0.890625q-0.53125 -0.3125 -1.171875 -0.3125q-0.671875 0 -1.234375 0.3125q-0.5625 0.3125 -0.90625 0.890625q-0.328125 0.5625 -0.328125 1.375q0 0.8125 0.328125 1.40625q0.34375 0.578125 0.90625 0.875q0.5625 0.296875 1.203125 0.296875zm10.200195 2.125q-1.21875 0 -2.1875 -0.59375q-0.96875 -0.609375 -1.53125 -1.65625q-0.5625 -1.0625 -0.5625 -2.453125q0 -1.390625 0.5625 -2.4375q0.5625 -1.0625 1.53125 -1.65625q0.96875 -0.59375 2.1875 -0.59375q0.640625 0 1.15625 0.1875q0.515625 0.1875 0.890625 0.5q0.390625 0.3125 0.59375 0.65625l0.140625 0l-0.140625 -1.25l0 -3.390625l2.265625 0l0 12.40625l-2.125 0l0 -1.0625l-0.140625 0q-0.203125 0.359375 -0.59375 0.65625q-0.375 0.296875 -0.890625 0.484375q-0.515625 0.203125 -1.15625 0.203125zm0.375 -2.09375q0.640625 0 1.1875 -0.328125q0.546875 -0.34375 0.875 -0.921875q0.34375 -0.578125 0.34375 -1.359375q0 -0.78125 -0.34375 -1.359375q-0.328125 -0.578125 -0.875 -0.890625q-0.546875 -0.328125 -1.1875 -0.328125q-0.625 0 -1.171875 0.328125q-0.546875 0.3125 -0.890625 0.890625q-0.328125 0.5625 -0.328125 1.359375q0 0.78125 0.328125 1.375q0.34375 0.59375 0.890625 0.921875q0.546875 0.3125 1.171875 0.3125zm10.850769 2.09375q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -12.40625l2.265625 0l0 12.40625l-2.265625 0z" fill-rule="nonzero"/><path fill="#20124d" d="m537.32556 147.10493l-1.234375 0l-0.1875 -5.828125l-0.078125 -2.25l-0.4375 1.3125l-1.390625 3.71875l-0.875 0l-1.3125 -3.578125l-0.4375 -1.453125l-0.03125 2.34375l-0.171875 5.734375l-1.203125 0l0.46875 -9.359375l1.5 0l1.265625 3.53125l0.40625 1.1875l0.390625 -1.1875l1.328125 -3.53125l1.546875 0l0.453125 9.359375zm7.7611694 -3.65625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm2.7143555 0.15625q0 -0.921875 0.25 -1.625q0.25 -0.71875 0.703125 -1.203125q0.46875 -0.5 1.109375 -0.75q0.65625 -0.25 1.453125 -0.25q0.34375 0 0.671875 0.046875q0.328125 0.03125 0.65625 0.125l0 -3.015625l1.25 0l0 10.109375l-1.109375 0l-0.046875 -1.359375q-0.515625 0.765625 -1.125 1.125q-0.609375 0.359375 -1.328125 0.359375q-0.609375 0 -1.078125 -0.25q-0.46875 -0.265625 -0.78125 -0.734375q-0.3125 -0.46875 -0.46875 -1.125q-0.15625 -0.65625 -0.15625 -1.453125zm1.265625 -0.078125q0 1.296875 0.375 1.9375q0.390625 0.640625 1.09375 0.640625q0.484375 0 1.0 -0.421875q0.53125 -0.421875 1.109375 -1.25l0 -3.34375q-0.3125 -0.140625 -0.6875 -0.203125q-0.359375 -0.078125 -0.734375 -0.078125q-1.015625 0 -1.59375 0.65625q-0.5625 0.65625 -0.5625 2.0625zm13.229919 -0.453125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm5.7299805 -4.9375l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm11.292419 7.140625q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm16.74115 -1.40625l-2.8125 0l0 2.921875l-1.234375 0l0 -2.921875l-2.8125 0l0 -1.078125l2.8125 0l0 -2.90625l1.234375 0l0 2.90625l2.8125 0l0 1.078125zm16.069275 -0.296875q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm9.214355 -0.125q0 0.890625 -0.25 1.59375q-0.234375 0.703125 -0.703125 1.203125q-0.453125 0.484375 -1.109375 0.75q-0.640625 0.25 -1.453125 0.25q-0.640625 0 -1.3125 -0.109375q-0.65625 -0.125 -1.3125 -0.390625l0 -9.6875l1.25 0l0 2.78125l-0.0625 1.328125q0.546875 -0.71875 1.15625 -1.015625q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.359375 0.140625 0.734375 0.234375q0.390625 0.078125 0.734375 0.078125q0.421875 0 0.8125 -0.125q0.390625 -0.140625 0.6875 -0.453125q0.296875 -0.328125 0.46875 -0.859375q0.1875 -0.53125 0.1875 -1.3125zm8.058044 -3.515625l0 7.0625q0 0.75 -0.21875 1.328125q-0.21875 0.59375 -0.625 0.984375q-0.390625 0.40625 -0.984375 0.609375q-0.578125 0.203125 -1.296875 0.203125q-0.53125 0 -1.046875 -0.09375q-0.5 -0.09375 -0.90625 -0.265625l0 -1.1875q0.21875 0.109375 0.46875 0.203125q0.265625 0.09375 0.53125 0.15625q0.265625 0.0625 0.53125 0.09375q0.28125 0.046875 0.53125 0.046875q0.828125 0 1.28125 -0.515625q0.46875 -0.515625 0.46875 -1.515625l0 -6.078125l-3.515625 0l0 -1.03125l4.78125 0zm-0.75 -3.015625q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.203125 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.0625 0.171875 -0.203125 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.21875 0 -0.40625 -0.078125q-0.171875 -0.078125 -0.296875 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.125 -0.140625 0.296875 -0.21875q0.1875 -0.078125 0.40625 -0.078125zm10.01123 6.234375q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.870544 3.890625q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.26123 0.171875q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm4.7142944 -6.0625l-2.125 0l0 -1.03125l3.390625 0l0 6.15625l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -5.125zm0.4375 -4.046875q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.21875 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.078125 0.171875 -0.21875 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.203125 0 -0.390625 -0.078125q-0.171875 -0.078125 -0.3125 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.140625 -0.140625 0.3125 -0.21875q0.1875 -0.078125 0.390625 -0.078125zm4.4956055 3.015625l1.421875 0l1.765625 4.75l0.375 1.15625l0.390625 -1.1875l1.75 -4.71875l1.359375 0l-2.8125 7.1875l-1.4375 0l-2.8125 -7.1875zm14.808044 3.21875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.964355 2.203125q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m610.1575 104.89501l0 -37.102364" fill-rule="evenodd"/><path stroke="#b7b7b7" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m610.1575 104.89501l0 -25.102364" fill-rule="evenodd"/><path fill="#b7b7b7" stroke="#b7b7b7" stroke-width="2.0" stroke-linecap="butt" d="m613.46094 79.79265l-3.3034668 -9.076195l-3.3034668 9.076195z" fill-rule="evenodd"/></g></svg>
\ No newline at end of file
+<svg version="1.1" viewBox="0.0 0.0 886.9475065616798 215.17322834645668" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><clipPath id="p.0"><path d="m0 0l886.9475 0l0 215.17323l-886.9475 0l0 -215.17323z" clip-rule="nonzero"/></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l886.9475 0l0 215.17323l-886.9475 0z" fill-rule="evenodd"/><path fill="#d9d2e9" d="m650.7113 139.07448l0 0c0 -3.2214813 2.6115112 -5.833008 5.833008 -5.833008l192.90088 0c1.5469971 0 3.0307007 0.6145477 4.1245728 1.7084503c1.0939331 1.0939026 1.708435 2.5775452 1.708435 4.1245575l0 58.34973c0 3.2214813 -2.6115112 5.833008 -5.833008 5.833008l-192.90088 0c-3.2214966 0 -5.833008 -2.6115265 -5.833008 -5.833008z" fill-rule="evenodd"/><path stroke="#b4a7d6" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m650.7113 139.07448l0 0c0 -3.2214813 2.6115112 -5.833008 5.833008 -5.833008l192.90088 0c1.5469971 0 3.0307007 0.6145477 4.1245728 1.7084503c1.0939331 1.0939026 1.708435 2.5775452 1.708435 4.1245575l0 58.34973c0 3.2214813 -2.6115112 5.833008 -5.833008 5.833008l-192.90088 0c-3.2214966 0 -5.833008 -2.6115265 -5.833008 -5.833008z" fill-rule="evenodd"/><path fill="#20124d" d="m662.826 156.38934l0 -12.40625l2.34375 0l0 12.40625l-2.34375 0zm4.8339233 0l0 -8.84375l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.890625q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm9.428589 -6.890625l0 -1.953125l1.65625 0l0 1.953125l-1.65625 0zm1.578125 6.890625l0 -9.328125q0 -0.984375 0.40625 -1.703125q0.40625 -0.734375 1.140625 -1.125q0.734375 -0.390625 1.734375 -0.390625q0.359375 0 0.71875 0.0625q0.359375 0.046875 0.6875 0.125l0 2.21875q-0.296875 -0.140625 -0.578125 -0.203125q-0.265625 -0.078125 -0.546875 -0.078125q-0.59375 0 -0.953125 0.34375q-0.34375 0.34375 -0.34375 0.953125l0 9.125l-2.265625 0zm2.171875 -6.890625l0 -1.953125l2.265625 0l0 1.953125l-2.265625 0zm7.406128 7.171875q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.84375l2.125 0l0 1.1875l0.140625 0q0.234375 -0.421875 0.59375 -0.734375q0.375 -0.328125 0.875 -0.515625q0.515625 -0.1875 1.078125 -0.1875q0.34375 0 0.625 0.046875q0.28125 0.046875 0.484375 0.140625l0 2.265625q-0.359375 -0.140625 -0.71875 -0.234375q-0.359375 -0.09375 -0.75 -0.09375q-0.671875 0 -1.171875 0.34375q-0.5 0.328125 -0.765625 0.921875q-0.25 0.578125 -0.25 1.296875l0 4.40625l-2.265625 0zm11.08905 0.28125q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.84375l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.890625q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm14.501099 0.28125q-1.34375 0 -2.40625 -0.59375q-1.046875 -0.609375 -1.640625 -1.671875q-0.59375 -1.0625 -0.59375 -2.4375q0 -1.359375 0.59375 -2.421875q0.59375 -1.0625 1.640625 -1.65625q1.0625 -0.609375 2.40625 -0.609375q1.46875 0 2.53125 0.625q1.0625 0.625 1.53125 1.796875l-2.09375 0.859375q-0.265625 -0.59375 -0.78125 -0.875q-0.5 -0.296875 -1.1875 -0.296875q-0.671875 0 -1.21875 0.328125q-0.53125 0.3125 -0.84375 0.890625q-0.3125 0.5625 -0.3125 1.359375q0 0.796875 0.3125 1.390625q0.3125 0.578125 0.84375 0.90625q0.546875 0.3125 1.21875 0.3125q0.765625 0 1.265625 -0.34375q0.5 -0.34375 0.8125 -0.921875l2.03125 0.890625q-0.515625 1.109375 -1.578125 1.796875q-1.0625 0.671875 -2.53125 0.671875zm9.635986 0q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm12.150818 0q-1.390625 0 -2.578125 -0.484375q-1.1875 -0.5 -2.0625 -1.390625q-0.875 -0.90625 -1.359375 -2.078125q-0.484375 -1.1875 -0.484375 -2.53125q0 -1.359375 0.484375 -2.53125q0.484375 -1.171875 1.359375 -2.0625q0.875 -0.90625 2.0625 -1.390625q1.1875 -0.5 2.578125 -0.5q1.375 0 2.546875 0.5q1.1875 0.484375 2.0625 1.390625q0.890625 0.890625 1.375 2.0625q0.484375 1.171875 0.484375 2.53125q0 1.34375 -0.484375 2.53125q-0.484375 1.171875 -1.375 2.078125q-0.875 0.890625 -2.0625 1.390625q-1.171875 0.484375 -2.546875 0.484375zm0 -2.21875q1.15625 0 2.09375 -0.53125q0.9375 -0.546875 1.484375 -1.5q0.5625 -0.96875 0.5625 -2.234375q0 -1.28125 -0.5625 -2.234375q-0.546875 -0.953125 -1.484375 -1.484375q-0.9375 -0.546875 -2.09375 -0.546875q-1.15625 0 -2.09375 0.546875q-0.921875 0.53125 -1.484375 1.484375q-0.546875 0.953125 -0.546875 2.234375q0 1.265625 0.546875 2.234375q0.5625 0.953125 1.484375 1.5q0.9375 0.53125 2.09375 0.53125zm13.270935 2.21875q-0.640625 0 -1.171875 -0.203125q-0.515625 -0.1875 -0.890625 -0.484375q-0.359375 -0.296875 -0.59375 -0.65625l-0.140625 0l0 1.0625l-2.125 0l0 -12.40625l2.265625 0l0 3.390625l-0.140625 1.25l0.140625 0q0.234375 -0.34375 0.59375 -0.65625q0.375 -0.3125 0.890625 -0.5q0.53125 -0.1875 1.171875 -0.1875q1.203125 0 2.171875 0.59375q0.96875 0.59375 1.53125 1.65625q0.5625 1.046875 0.5625 2.4375q0 1.390625 -0.5625 2.453125q-0.5625 1.046875 -1.53125 1.65625q-0.96875 0.59375 -2.171875 0.59375zm-0.40625 -2.09375q0.640625 0 1.1875 -0.3125q0.546875 -0.328125 0.875 -0.921875q0.34375 -0.59375 0.34375 -1.375q0 -0.796875 -0.34375 -1.359375q-0.328125 -0.578125 -0.875 -0.890625q-0.546875 -0.328125 -1.1875 -0.328125q-0.625 0 -1.171875 0.328125q-0.53125 0.3125 -0.875 0.890625q-0.34375 0.578125 -0.34375 1.359375q0 0.78125 0.34375 1.359375q0.34375 0.578125 0.875 0.921875q0.546875 0.328125 1.171875 0.328125zm5.850708 5.734375q-0.328125 0 -0.59375 -0.03125q-0.28125 -0.03125 -0.59375 -0.09375l0 -2.203125q0.1875 0.109375 0.421875 0.171875q0.234375 0.078125 0.5 0.078125q0.421875 0 0.59375 -0.265625q0.1875 -0.265625 0.1875 -0.765625l0 -9.65625l2.265625 0l0 9.703125q0 1.109375 -0.390625 1.78125q-0.375 0.671875 -1.015625 0.96875q-0.625 0.3125 -1.375 0.3125zm1.65625 -13.734375q-0.609375 0 -1.046875 -0.421875q-0.421875 -0.4375 -0.421875 -1.046875q0 -0.609375 0.421875 -1.03125q0.4375 -0.421875 1.046875 -0.421875q0.609375 0 1.03125 0.421875q0.421875 0.421875 0.421875 1.03125q0 0.609375 -0.421875 1.046875q-0.421875 0.421875 -1.03125 0.421875zm7.453308 10.09375q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm10.135193 0q-1.34375 0 -2.40625 -0.59375q-1.046875 -0.609375 -1.640625 -1.671875q-0.59375 -1.0625 -0.59375 -2.4375q0 -1.359375 0.59375 -2.421875q0.59375 -1.0625 1.640625 -1.65625q1.0625 -0.609375 2.40625 -0.609375q1.46875 0 2.53125 0.625q1.0625 0.625 1.53125 1.796875l-2.09375 0.859375q-0.265625 -0.59375 -0.78125 -0.875q-0.5 -0.296875 -1.1875 -0.296875q-0.671875 0 -1.21875 0.328125q-0.53125 0.3125 -0.84375 0.890625q-0.3125 0.5625 -0.3125 1.359375q0 0.796875 0.3125 1.390625q0.3125 0.578125 0.84375 0.90625q0.546875 0.3125 1.21875 0.3125q0.765625 0 1.265625 -0.34375q0.5 -0.34375 0.8125 -0.921875l2.03125 0.890625q-0.515625 1.109375 -1.578125 1.796875q-1.0625 0.671875 -2.53125 0.671875zm4.8391724 -7.171875l0 -1.953125l1.625 0l0 1.953125l-1.625 0zm4.46875 7.03125q-1.375 0 -2.15625 -0.78125q-0.78125 -0.796875 -0.78125 -2.1875l0 -8.5l2.28125 0l0 8.09375q0 0.640625 0.25 0.9375q0.265625 0.296875 0.859375 0.296875q0.265625 0 0.5 -0.078125q0.25 -0.078125 0.625 -0.296875l0 2.21875q-0.390625 0.140625 -0.78125 0.21875q-0.390625 0.078125 -0.796875 0.078125zm-0.75 -7.03125l0 -1.953125l2.25 0l0 1.953125l-2.25 0zm4.128662 6.890625l0 -8.84375l2.265625 0l0 8.84375l-2.265625 0zm1.140625 -9.8125q-0.609375 0 -1.046875 -0.421875q-0.421875 -0.4375 -0.421875 -1.046875q0 -0.609375 0.421875 -1.03125q0.4375 -0.421875 1.046875 -0.421875q0.609375 0 1.03125 0.421875q0.421875 0.421875 0.421875 1.03125q0 0.609375 -0.421875 1.046875q-0.421875 0.421875 -1.03125 0.421875zm6.031433 9.8125l-3.75 -8.84375l2.59375 0l2.234375 5.765625l0.140625 0l2.265625 -5.765625l2.546875 0l-3.78125 8.84375l-2.25 0zm10.986816 0.28125q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625z" fill-rule="nonzero"/><path fill="#20124d" d="m668.93536 174.82935l-1.4375 0l-1.390625 -2.984375q-0.15625 -0.34375 -0.328125 -0.5625q-0.15625 -0.234375 -0.34375 -0.359375q-0.1875 -0.140625 -0.421875 -0.203125q-0.21875 -0.0625 -0.5 -0.0625l-0.609375 0l0 4.171875l-1.265625 0l0 -9.359375l2.5 0q0.8125 0 1.390625 0.1875q0.59375 0.171875 0.96875 0.5q0.390625 0.328125 0.5625 0.78125q0.171875 0.453125 0.171875 1.0q0 0.4375 -0.125 0.828125q-0.125 0.390625 -0.390625 0.71875q-0.25 0.3125 -0.625 0.546875q-0.375 0.21875 -0.859375 0.34375q0.390625 0.125 0.65625 0.46875q0.28125 0.34375 0.578125 0.90625l1.46875 3.078125zm-2.03125 -6.78125q0 -0.75 -0.46875 -1.125q-0.46875 -0.375 -1.328125 -0.375l-1.203125 0l0 3.09375l1.03125 0q0.453125 0 0.8125 -0.09375q0.359375 -0.109375 0.609375 -0.3125q0.265625 -0.203125 0.40625 -0.5q0.140625 -0.296875 0.140625 -0.6875zm9.792419 2.8125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm2.9174805 0.71875q0 -0.78125 0.203125 -1.46875q0.203125 -0.703125 0.625 -1.21875q0.4375 -0.53125 1.09375 -0.828125q0.671875 -0.3125 1.59375 -0.3125q0.359375 0 0.71875 0.0625q0.359375 0.046875 0.765625 0.171875l1.09375 -0.28125l0 10.25l-1.25 0l0 -2.71875l0.0625 -1.53125q-1.015625 1.4375 -2.421875 1.4375q-0.625 0 -1.09375 -0.25q-0.46875 -0.265625 -0.78125 -0.734375q-0.296875 -0.46875 -0.453125 -1.125q-0.15625 -0.65625 -0.15625 -1.453125zm1.265625 -0.078125q0 0.59375 0.09375 1.078125q0.09375 0.484375 0.265625 0.8125q0.1875 0.328125 0.46875 0.515625q0.28125 0.171875 0.640625 0.171875q0.484375 0 1.0 -0.421875q0.53125 -0.421875 1.109375 -1.25l0 -3.34375q-0.28125 -0.125 -0.65625 -0.203125q-0.359375 -0.09375 -0.765625 -0.09375q-1.046875 0 -1.609375 0.703125q-0.546875 0.6875 -0.546875 2.03125zm12.933044 3.515625l-1.125 0l-0.03125 -1.15625q-0.328125 0.375 -0.625 0.625q-0.28125 0.234375 -0.578125 0.390625q-0.28125 0.140625 -0.578125 0.203125q-0.28125 0.0625 -0.59375 0.0625q-1.109375 0 -1.6875 -0.640625q-0.5625 -0.65625 -0.5625 -1.96875l0 -4.703125l1.25 0l0 4.59375q0 1.65625 1.25 1.65625q0.21875 0 0.4375 -0.0625q0.21875 -0.078125 0.453125 -0.234375q0.25 -0.171875 0.515625 -0.453125q0.28125 -0.296875 0.625 -0.734375l0 -4.765625l1.25 0l0 7.1875zm8.35498 -3.96875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.964294 2.203125q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.16748 1.859375q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm7.2924194 -3.21875l-4.28125 0l0 -1.171875l4.28125 0l0 1.171875zm8.714355 1.359375q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.511169 -1.765625q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm9.26123 -0.296875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.870544 3.890625q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm4.9174805 -5.890625l-2.125 0l0 -1.03125l3.390625 0l0 6.15625l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -5.125zm0.4375 -4.046875q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.21875 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.078125 0.171875 -0.21875 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.203125 0 -0.390625 -0.078125q-0.171875 -0.078125 -0.3125 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.140625 -0.140625 0.3125 -0.21875q0.1875 -0.078125 0.390625 -0.078125zm11.542419 1.25q-0.96875 -0.203125 -1.6875 -0.203125q-1.671875 0 -1.671875 1.75l0 1.265625l3.140625 0l0 1.03125l-3.140625 0l0 5.109375l-1.265625 0l0 -5.109375l-2.3125 0l0 -1.03125l2.3125 0l0 -1.1875q0 -2.875 2.984375 -2.875q0.75 0 1.640625 0.171875l0 1.078125zm-7.515625 1.765625l0 0zm11.651855 1.03125l-2.125 0l0 -1.03125l3.390625 0l0 6.15625l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -5.125zm0.4375 -4.046875q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.21875 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.078125 0.171875 -0.21875 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.203125 0 -0.390625 -0.078125q-0.171875 -0.078125 -0.3125 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.140625 -0.140625 0.3125 -0.21875q0.1875 -0.078125 0.390625 -0.078125zm10.761169 9.9375q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625z" fill-rule="nonzero"/><path fill="#20124d" d="m668.826 189.1731q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm9.214294 -0.125q0 0.890625 -0.25 1.59375q-0.234375 0.703125 -0.703125 1.203125q-0.453125 0.484375 -1.109375 0.75q-0.640625 0.25 -1.453125 0.25q-0.640625 0 -1.3125 -0.109375q-0.65625 -0.125 -1.3125 -0.390625l0 -9.6875l1.25 0l0 2.78125l-0.0625 1.328125q0.546875 -0.71875 1.15625 -1.015625q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.359375 0.140625 0.734375 0.234375q0.390625 0.078125 0.734375 0.078125q0.421875 0 0.8125 -0.125q0.390625 -0.140625 0.6875 -0.453125q0.296875 -0.328125 0.46875 -0.859375q0.1875 -0.53125 0.1875 -1.3125zm8.058105 -3.515625l0 7.0625q0 0.75 -0.21875 1.328125q-0.21875 0.59375 -0.625 0.984375q-0.390625 0.40625 -0.984375 0.609375q-0.578125 0.203125 -1.296875 0.203125q-0.53125 0 -1.046875 -0.09375q-0.5 -0.09375 -0.90625 -0.265625l0 -1.1875q0.21875 0.109375 0.46875 0.203125q0.265625 0.09375 0.53125 0.15625q0.265625 0.0625 0.53125 0.09375q0.28125 0.046875 0.53125 0.046875q0.828125 0 1.28125 -0.515625q0.46875 -0.515625 0.46875 -1.515625l0 -6.078125l-3.515625 0l0 -1.03125l4.78125 0zm-0.75 -3.015625q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.203125 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.0625 0.171875 -0.203125 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.21875 0 -0.40625 -0.078125q-0.171875 -0.078125 -0.296875 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.125 -0.140625 0.296875 -0.21875q0.1875 -0.078125 0.40625 -0.078125zm10.011169 6.234375q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.870605 3.890625q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.261169 0.171875q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm4.7143555 -6.0625l-2.125 0l0 -1.03125l3.390625 0l0 6.15625l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -5.125zm0.4375 -4.046875q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.21875 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.078125 0.171875 -0.21875 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.203125 0 -0.390625 -0.078125q-0.171875 -0.078125 -0.3125 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.140625 -0.140625 0.3125 -0.21875q0.1875 -0.078125 0.390625 -0.078125zm4.4955444 3.015625l1.421875 0l1.765625 4.75l0.375 1.15625l0.390625 -1.1875l1.75 -4.71875l1.359375 0l-2.8125 7.1875l-1.4375 0l-2.8125 -7.1875zm14.808105 3.21875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.964294 2.203125q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875z" fill-rule="nonzero"/><path fill="#ead1dc" d="m626.31757 22.082747l0 0c0 -2.450529 1.9865723 -4.4370766 4.4370728 -4.4370766l244.48022 0c1.1767578 0 2.305359 0.4674759 3.1374512 1.2995892c0.8321533 0.83211327 1.2996216 1.960701 1.2996216 3.1374874l0 44.38569c0 2.450531 -1.9865723 4.4370728 -4.4370728 4.4370728l-244.48022 0c-2.4505005 0 -4.4370728 -1.9865417 -4.4370728 -4.4370728z" fill-rule="evenodd"/><path stroke="#d5a6bd" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m626.31757 22.082747l0 0c0 -2.450529 1.9865723 -4.4370766 4.4370728 -4.4370766l244.48022 0c1.1767578 0 2.305359 0.4674759 3.1374512 1.2995892c0.8321533 0.83211327 1.2996216 1.960701 1.2996216 3.1374874l0 44.38569c0 2.450531 -1.9865723 4.4370728 -4.4370728 4.4370728l-244.48022 0c-2.4505005 0 -4.4370728 -1.9865417 -4.4370728 -4.4370728z" fill-rule="evenodd"/><path fill="#4c1130" d="m638.02344 41.41559l0 -12.406248l2.34375 0l0 10.187498l5.25 0l0 2.21875l-7.59375 0zm9.478394 0l0 -12.406248l2.34375 0l0 10.187498l5.25 0l0 2.21875l-7.59375 0zm9.478455 0l0 -12.406248l3.015625 0l3.296875 8.718748l0.125 0l3.296875 -8.718748l3.03125 0l0 12.406248l-2.3125 0l0 -6.109375l0.125 -2.0625l-0.125 0l-3.15625 8.171875l-1.828125 0l-3.171875 -8.171875l-0.140625 0l0.140625 2.0625l0 6.109375l-2.296875 0zm15.577881 0l0 -12.406248l4.84375 0q1.078125 0 1.9375 0.453125q0.859375 0.4375 1.359375 1.171875q0.5 0.71875 0.5 1.6093731q0 0.96875 -0.484375 1.65625q-0.46875 0.671875 -1.171875 1.015625l0 0.140625q0.953125 0.328125 1.53125 1.09375q0.578125 0.75 0.578125 1.8125q0 1.0625 -0.546875 1.84375q-0.546875 0.765625 -1.46875 1.1875q-0.921875 0.421875 -2.0625 0.421875l-5.015625 0zm1.296875 -5.34375l0 -2.0l3.375 0q0.546875 0 0.90625 -0.203125q0.375 -0.203125 0.578125 -0.546875q0.203125 -0.34375 0.203125 -0.75q0 -0.40625 -0.203125 -0.7343731q-0.1875 -0.328125 -0.546875 -0.53125q-0.359375 -0.203125 -0.859375 -0.203125l-2.40625 0l0 8.187498l2.59375 0q0.59375 0 0.984375 -0.203125q0.40625 -0.21875 0.609375 -0.578125q0.203125 -0.375 0.203125 -0.8125q0 -0.46875 -0.203125 -0.828125q-0.203125 -0.375 -0.625 -0.578125q-0.421875 -0.21875 -1.046875 -0.21875l-3.5625 0zm12.216614 5.625q-0.9375 0 -1.65625 -0.375q-0.71875 -0.375 -1.140625 -1.046875q-0.40625 -0.671875 -0.40625 -1.5625q0 -0.921875 0.46875 -1.578125q0.484375 -0.65625 1.28125 -1.015625q0.8125 -0.375 1.796875 -0.375q0.546875 0 0.984375 0.0625q0.4375 0.0625 0.78125 0.15625q0.34375 0.078125 0.578125 0.1875l0 -0.390625q0 -0.703125 -0.546875 -1.15625q-0.53125 -0.46875 -1.46875 -0.46875q-0.625 0 -1.203125 0.296875q-0.578125 0.28125 -0.953125 0.75l-1.46875 -1.140625q0.4375 -0.5625 1.0 -0.953125q0.578125 -0.390625 1.265625 -0.578125q0.703125 -0.203125 1.46875 -0.203125q2.03125 0 3.078125 0.9375q1.0625 0.921875 1.0625 2.734375l0 5.4375l-2.234375 0l0 -0.90625l-0.140625 0q-0.25 0.3125 -0.609375 0.59375q-0.359375 0.265625 -0.84375 0.421875q-0.484375 0.171875 -1.09375 0.171875zm0.53125 -1.765625q0.703125 0 1.171875 -0.296875q0.484375 -0.3125 0.734375 -0.796875q0.25 -0.484375 0.25 -1.03125q-0.390625 -0.1875 -0.875 -0.296875q-0.484375 -0.109375 -0.984375 -0.109375q-1.0 0 -1.390625 0.390625q-0.375 0.375 -0.375 0.921875q0 0.515625 0.375 0.875q0.375 0.34375 1.09375 0.34375zm10.609985 1.765625q-1.34375 0 -2.40625 -0.59375q-1.046875 -0.609375 -1.640625 -1.671875q-0.59375 -1.0625 -0.59375 -2.4375q0 -1.359375 0.59375 -2.421875q0.59375 -1.0625 1.640625 -1.65625q1.0625 -0.609375 2.40625 -0.609375q1.46875 0 2.53125 0.625q1.0625 0.625 1.53125 1.796875l-2.09375 0.859375q-0.265625 -0.59375 -0.78125 -0.875q-0.5 -0.296875 -1.1875 -0.296875q-0.671875 0 -1.21875 0.328125q-0.53125 0.3125 -0.84375 0.890625q-0.3125 0.5625 -0.3125 1.359375q0 0.796875 0.3125 1.390625q0.3125 0.578125 0.84375 0.90625q0.546875 0.3125 1.21875 0.3125q0.765625 0 1.265625 -0.34375q0.5 -0.34375 0.8125 -0.921875l2.03125 0.890625q-0.515625 1.109375 -1.578125 1.796875q-1.0625 0.671875 -2.53125 0.671875zm5.668701 -0.28125l0 -12.406248l2.265625 0l0 12.406248l-2.265625 0zm1.328125 -1.859375l0 -2.796875l4.234375 -4.1875l2.78125 0l0 0.140625l-7.015625 6.84375zm4.484375 1.859375l-2.96875 -4.765625l1.578125 -1.546875l4.078125 6.171875l0 0.140625l-2.6875 0zm7.7198486 0.28125q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.84375l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.890625q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm14.141724 0.28125q-1.21875 0 -2.1875 -0.59375q-0.96875 -0.609375 -1.53125 -1.65625q-0.5625 -1.0625 -0.5625 -2.453125q0 -1.390625 0.5625 -2.4375q0.5625 -1.0625 1.53125 -1.65625q0.96875 -0.59375 2.1875 -0.59375q0.640625 0 1.15625 0.1875q0.515625 0.1875 0.890625 0.5q0.390625 0.3125 0.59375 0.65625l0.140625 0l-0.140625 -1.25l0 -3.390623l2.265625 0l0 12.406248l-2.125 0l0 -1.0625l-0.140625 0q-0.203125 0.359375 -0.59375 0.65625q-0.375 0.296875 -0.890625 0.484375q-0.515625 0.203125 -1.15625 0.203125zm0.375 -2.09375q0.640625 0 1.1875 -0.328125q0.546875 -0.34375 0.875 -0.921875q0.34375 -0.578125 0.34375 -1.359375q0 -0.78125 -0.34375 -1.359375q-0.328125 -0.578125 -0.875 -0.890625q-0.546875 -0.328125 -1.1875 -0.328125q-0.625 0 -1.171875 0.328125q-0.546875 0.3125 -0.890625 0.890625q-0.328125 0.5625 -0.328125 1.359375q0 0.78125 0.328125 1.375q0.34375 0.59375 0.890625 0.921875q0.546875 0.3125 1.171875 0.3125zm7.022644 1.8125l0 -12.406248l4.359375 0q1.203125 0 2.15625 0.5q0.953125 0.484375 1.515625 1.375q0.5625 0.875 0.5625 2.046873q0 1.15625 -0.5625 2.046875q-0.5625 0.890625 -1.515625 1.390625q-0.953125 0.484375 -2.15625 0.484375l-3.0625 0l0 -2.21875l3.140625 0q0.609375 0 1.015625 -0.234375q0.421875 -0.25 0.625 -0.640625q0.203125 -0.390625 0.203125 -0.828125q0 -0.453125 -0.203125 -0.828125q-0.203125 -0.3906231 -0.625 -0.6249981q-0.40625 -0.25 -1.015625 -0.25l-2.09375 0l0 10.187498l-2.34375 0zm14.008362 0.28125q-1.375 0 -2.453125 -0.609375q-1.0625 -0.625 -1.65625 -1.6875q-0.59375 -1.0625 -0.59375 -2.40625q0 -1.328125 0.59375 -2.390625q0.59375 -1.078125 1.65625 -1.6875q1.078125 -0.609375 2.453125 -0.609375q1.390625 0 2.4375 0.625q1.0625 0.625 1.65625 1.6875q0.609375 1.046875 0.609375 2.375q0 1.34375 -0.609375 2.40625q-0.59375 1.0625 -1.65625 1.6875q-1.046875 0.609375 -2.4375 0.609375zm0 -2.125q0.671875 0 1.203125 -0.296875q0.546875 -0.296875 0.890625 -0.875q0.34375 -0.59375 0.34375 -1.40625q0 -0.8125 -0.34375 -1.375q-0.34375 -0.578125 -0.890625 -0.890625q-0.53125 -0.3125 -1.171875 -0.3125q-0.671875 0 -1.234375 0.3125q-0.5625 0.3125 -0.90625 0.890625q-0.328125 0.5625 -0.328125 1.375q0 0.8125 0.328125 1.40625q0.34375 0.578125 0.90625 0.875q0.5625 0.296875 1.203125 0.296875zm10.62207 2.125q-1.375 0 -2.453125 -0.609375q-1.0625 -0.625 -1.65625 -1.6875q-0.59375 -1.0625 -0.59375 -2.40625q0 -1.328125 0.59375 -2.390625q0.59375 -1.078125 1.65625 -1.6875q1.078125 -0.609375 2.453125 -0.609375q1.390625 0 2.4375 0.625q1.0625 0.625 1.65625 1.6875q0.609375 1.046875 0.609375 2.375q0 1.34375 -0.609375 2.40625q-0.59375 1.0625 -1.65625 1.6875q-1.046875 0.609375 -2.4375 0.609375zm0 -2.125q0.671875 0 1.203125 -0.296875q0.546875 -0.296875 0.890625 -0.875q0.34375 -0.59375 0.34375 -1.40625q0 -0.8125 -0.34375 -1.375q-0.34375 -0.578125 -0.890625 -0.890625q-0.53125 -0.3125 -1.171875 -0.3125q-0.671875 0 -1.234375 0.3125q-0.5625 0.3125 -0.90625 0.890625q-0.328125 0.5625 -0.328125 1.375q0 0.8125 0.328125 1.40625q0.34375 0.578125 0.90625 0.875q0.5625 0.296875 1.203125 0.296875zm6.4033203 1.84375l0 -12.406248l2.265625 0l0 12.406248l-2.265625 0z" fill-rule="nonzero"/><path fill="#4c1130" d="m643.4453 57.902466q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.448669 -2.015625q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm5.7299805 -4.9375l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm11.683044 5.125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.870605 3.890625q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.261169 0.171875q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm8.526855 -3.5625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm3.3705444 -3.59375l1.140625 0l0.03125 1.328125q0.640625 -0.765625 1.25 -1.109375q0.625 -0.34375 1.25 -0.34375q1.125 0 1.703125 0.71875q0.578125 0.71875 0.53125 2.15625l-1.265625 0q0.03125 -0.953125 -0.265625 -1.375q-0.296875 -0.421875 -0.875 -0.421875q-0.25 0 -0.515625 0.09375q-0.25 0.078125 -0.515625 0.28125q-0.265625 0.1875 -0.5625 0.5q-0.296875 0.3125 -0.640625 0.75l0 4.609375l-1.265625 0l0 -7.1875zm10.651855 -0.125q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm18.506775 5.0l-0.53125 0q-1.375 0 -2.0625 -0.65625q-0.671875 -0.640625 -0.671875 -1.953125l0 -2.46875q0 -0.34375 -0.078125 -0.625q-0.078125 -0.28125 -0.28125 -0.46875q-0.1875 -0.1875 -0.515625 -0.28125q-0.328125 -0.109375 -0.8125 -0.109375l-0.3125 0l0 -0.984375l0.3125 0q0.515625 0 0.84375 -0.078125q0.328125 -0.09375 0.515625 -0.265625q0.1875 -0.1875 0.25 -0.453125q0.078125 -0.28125 0.078125 -0.640625l0 -1.703125q0 -0.59375 0.140625 -1.078125q0.15625 -0.484375 0.46875 -0.828125q0.328125 -0.34375 0.84375 -0.515625q0.53125 -0.1875 1.28125 -0.1875l0.53125 0l0 1.0l-0.421875 0q-1.65625 0 -1.65625 1.609375l0 1.671875q0 1.734375 -1.515625 1.96875q1.515625 0.140625 1.515625 1.953125l0 2.453125q0 1.640625 1.65625 1.640625l0.421875 0l0 1.0zm8.917419 -6.65625q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm9.44873 0.015625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm9.339294 -0.0625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm5.5268555 -5.5l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm8.495544 1.78125q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm17.850525 2.0625l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm9.26123 1.3125q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.058044 0q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.16748 1.859375q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm2.7611694 -10.265625l0.53125 0q1.375 0 2.046875 0.65625q0.671875 0.640625 0.671875 1.953125l0 1.65625q0 0.34375 0.078125 0.625q0.078125 0.265625 0.28125 0.46875q0.203125 0.1875 0.53125 0.296875q0.328125 0.09375 0.8125 0.09375l0.3125 0l0 0.984375l-0.3125 0q-0.515625 0 -0.859375 0.09375q-0.328125 0.078125 -0.515625 0.265625q-0.1875 0.171875 -0.265625 0.4375q-0.0625 0.265625 -0.0625 0.640625l0 2.515625q0 0.59375 -0.140625 1.078125q-0.140625 0.484375 -0.46875 0.8125q-0.3125 0.34375 -0.84375 0.53125q-0.515625 0.1875 -1.265625 0.1875l-0.53125 0l0 -1.0l0.421875 0q1.65625 0 1.65625 -1.609375l0 -2.484375q0 -1.75 1.515625 -1.953125q-1.53125 -0.171875 -1.53125 -1.96875l0 -1.640625q0 -1.640625 -1.640625 -1.640625l-0.421875 0l0 -1.0z" fill-rule="nonzero"/><path fill="#d9ead3" d="m334.4908 18.114243l0 0c0 -2.45053 1.9865417 -4.4370775 4.4370728 -4.4370775l172.79514 0c1.1768188 0 2.305359 0.46747684 3.1375122 1.2995901c0.8320923 0.83211327 1.2995605 1.960701 1.2995605 3.1374874l0 44.38569c0 2.450531 -1.9865112 4.4370728 -4.4370728 4.4370728l-172.79514 0c-2.450531 0 -4.4370728 -1.9865417 -4.4370728 -4.4370728z" fill-rule="evenodd"/><path stroke="#b6d7a8" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m334.4908 18.114243l0 0c0 -2.45053 1.9865417 -4.4370775 4.4370728 -4.4370775l172.79514 0c1.1768188 0 2.305359 0.46747684 3.1375122 1.2995901c0.8320923 0.83211327 1.2995605 1.960701 1.2995605 3.1374874l0 44.38569c0 2.450531 -1.9865112 4.4370728 -4.4370728 4.4370728l-172.79514 0c-2.450531 0 -4.4370728 -1.9865417 -4.4370728 -4.4370728z" fill-rule="evenodd"/><path fill="#274e13" d="m346.19662 37.447086l0 -12.40625l2.34375 0l0 12.40625l-2.34375 0zm1.296875 -5.234375l0 -2.21875l7.296875 0l0 2.21875l-7.296875 0zm6.25 5.234375l0 -12.40625l2.34375 0l0 12.40625l-2.34375 0zm7.5920715 0l0 -11.234375l2.34375 0l0 11.234375l-2.34375 0zm-3.46875 -10.1875l0 -2.21875l9.28125 0l0 2.21875l-9.28125 0zm13.935028 10.1875l0 -11.234375l2.34375 0l0 11.234375l-2.34375 0zm-3.46875 -10.1875l0 -2.21875l9.28125 0l0 2.21875l-9.28125 0zm11.064178 10.1875l0 -12.40625l4.359375 0q1.203125 0 2.15625 0.5q0.953125 0.484375 1.515625 1.375q0.5625 0.875 0.5625 2.046875q0 1.15625 -0.5625 2.046875q-0.5625 0.890625 -1.515625 1.390625q-0.953125 0.484375 -2.15625 0.484375l-3.0625 0l0 -2.21875l3.140625 0q0.609375 0 1.015625 -0.234375q0.421875 -0.25 0.625 -0.640625q0.203125 -0.390625 0.203125 -0.828125q0 -0.453125 -0.203125 -0.828125q-0.203125 -0.390625 -0.625 -0.625q-0.40625 -0.25 -1.015625 -0.25l-2.09375 0l0 10.1875l-2.34375 0zm10.535431 0l0 -12.40625l4.515625 0q1.25 0 2.171875 0.5q0.9375 0.5 1.453125 1.390625q0.515625 0.875 0.515625 2.03125q0 0.84375 -0.359375 1.546875q-0.34375 0.703125 -0.96875 1.21875q-0.609375 0.5 -1.4375 0.78125q-0.8125 0.28125 -1.75 0.28125l-2.84375 0l0 -2.15625l3.203125 0q0.546875 0 0.9375 -0.21875q0.40625 -0.234375 0.640625 -0.625q0.234375 -0.390625 0.234375 -0.875q0 -0.4375 -0.203125 -0.828125q-0.203125 -0.390625 -0.609375 -0.625q-0.390625 -0.25 -0.96875 -0.25l-2.1875 0l0 10.234375l-2.34375 0zm2.734375 -5.625l2.734375 0l3.84375 5.484375l0 0.140625l-2.671875 0l-3.90625 -5.625zm12.244476 5.90625q-1.375 0 -2.453125 -0.609375q-1.0625 -0.625 -1.65625 -1.6875q-0.59375 -1.0625 -0.59375 -2.40625q0 -1.328125 0.59375 -2.390625q0.59375 -1.078125 1.65625 -1.6875q1.078125 -0.609375 2.453125 -0.609375q1.390625 0 2.4375 0.625q1.0625 0.625 1.65625 1.6875q0.609375 1.046875 0.609375 2.375q0 1.34375 -0.609375 2.40625q-0.59375 1.0625 -1.65625 1.6875q-1.046875 0.609375 -2.4375 0.609375zm0 -2.125q0.671875 0 1.203125 -0.296875q0.546875 -0.296875 0.890625 -0.875q0.34375 -0.59375 0.34375 -1.40625q0 -0.8125 -0.34375 -1.375q-0.34375 -0.578125 -0.890625 -0.890625q-0.53125 -0.3125 -1.171875 -0.3125q-0.671875 0 -1.234375 0.3125q-0.5625 0.3125 -0.90625 0.890625q-0.328125 0.5625 -0.328125 1.375q0 0.8125 0.328125 1.40625q0.34375 0.578125 0.90625 0.875q0.5625 0.296875 1.203125 0.296875zm9.590851 2.125q-1.625 0 -2.453125 -1.0q-0.8125 -1.015625 -0.8125 -2.75l0 -5.375l2.28125 0l0 5.09375q0 0.90625 0.4375 1.421875q0.4375 0.515625 1.140625 0.515625q0.671875 0 1.140625 -0.34375q0.46875 -0.34375 0.71875 -0.90625q0.25 -0.578125 0.25 -1.265625l0 -4.515625l2.265625 0l0 8.84375l-2.125 0l0 -1.109375l-0.140625 0q-0.265625 0.421875 -0.6875 0.734375q-0.40625 0.3125 -0.921875 0.484375q-0.5 0.171875 -1.09375 0.171875zm6.501068 -7.171875l0 -1.953125l1.625 0l0 1.953125l-1.625 0zm4.46875 7.03125q-1.375 0 -2.15625 -0.78125q-0.78125 -0.796875 -0.78125 -2.1875l0 -8.5l2.28125 0l0 8.09375q0 0.640625 0.25 0.9375q0.265625 0.296875 0.859375 0.296875q0.265625 0 0.5 -0.078125q0.25 -0.078125 0.625 -0.296875l0 2.21875q-0.390625 0.140625 -0.78125 0.21875q-0.390625 0.078125 -0.796875 0.078125zm-0.75 -7.03125l0 -1.953125l2.25 0l0 1.953125l-2.25 0zm7.8359375 7.171875q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625z" fill-rule="nonzero"/><path fill="#274e13" d="m352.07162 52.16834q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm7.808075 3.671875l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm9.370575 3.171875q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm8.04245 0.09375l-1.25 0l0 -4.59375q0 -0.828125 -0.3125 -1.234375q-0.3125 -0.40625 -0.890625 -0.40625q-0.25 0 -0.46875 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.28125 0.28125 -0.640625 0.71875l0 4.765625l-1.25 0l0 -10.109375l1.25 0l0 2.921875l-0.046875 1.140625q0.296875 -0.359375 0.578125 -0.59375q0.28125 -0.25 0.5625 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.078125 0 1.65625 0.65625q0.59375 0.65625 0.59375 1.96875l0 4.6875zm5.16745 -7.3125q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.006775 -8.046875l-4.90625 11.640625l-1.1875 0l4.90625 -11.640625l1.1875 0zm7.870575 9.84375q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.72995 -3.390625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.1987 3.59375l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0737 -3.71875q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm5.6362 -5.421875l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm11.683075 5.125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm9.0737 4.0625q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm4.714325 -6.0625l-2.125 0l0 -1.03125l3.390625 0l0 6.15625l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -5.125zm0.4375 -4.046875q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.21875 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.078125 0.171875 -0.21875 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.203125 0 -0.390625 -0.078125q-0.171875 -0.078125 -0.3125 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.140625 -0.140625 0.3125 -0.21875q0.1875 -0.078125 0.390625 -0.078125zm11.433075 6.546875q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm3.0737 -3.59375l1.109375 0l0.046875 1.15625q0.328125 -0.359375 0.609375 -0.609375q0.296875 -0.25 0.578125 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.109375 0 1.671875 0.65625q0.578125 0.65625 0.578125 1.96875l0 4.6875l-1.25 0l0 -4.59375q0 -0.84375 -0.3125 -1.234375q-0.3125 -0.40625 -0.9375 -0.40625q-0.234375 0 -0.453125 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.265625 0.28125 -0.609375 0.71875l0 4.765625l-1.25 0l0 -7.1875zm13.745575 5.234375q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m204.56693 41.165356l129.92126 -0.8503952" fill-rule="evenodd"/><path stroke="#b7b7b7" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m216.56667 41.08681l117.921524 -0.7718506" fill-rule="evenodd"/><path fill="#b7b7b7" stroke="#b7b7b7" stroke-width="2.0" stroke-linecap="butt" d="m216.54504 37.783417l-9.054367 3.3628006l9.09761 3.243988z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m516.1601 40.307087l105.921265 0" fill-rule="evenodd"/><path stroke="#b7b7b7" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m516.1601 40.307087l93.921265 0" fill-rule="evenodd"/><path fill="#b7b7b7" stroke="#b7b7b7" stroke-width="2.0" stroke-linecap="butt" d="m610.08136 43.61055l9.076172 -3.303463l-9.076172 -3.3034668z" fill-rule="evenodd"/><path fill="#ead1dc" d="m622.084 18.114243l0 0c0 -2.45053 1.9865723 -4.4370775 4.4370728 -4.4370775l244.48016 0c1.1768188 0 2.30542 0.46747684 3.1375122 1.2995901c0.8320923 0.83211327 1.2995605 1.960701 1.2995605 3.1374874l0 44.38569c0 2.450531 -1.9865112 4.4370728 -4.4370728 4.4370728l-244.48016 0c-2.4505005 0 -4.4370728 -1.9865417 -4.4370728 -4.4370728z" fill-rule="evenodd"/><path stroke="#d5a6bd" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m622.084 18.114243l0 0c0 -2.45053 1.9865723 -4.4370775 4.4370728 -4.4370775l244.48016 0c1.1768188 0 2.30542 0.46747684 3.1375122 1.2995901c0.8320923 0.83211327 1.2995605 1.960701 1.2995605 3.1374874l0 44.38569c0 2.450531 -1.9865112 4.4370728 -4.4370728 4.4370728l-244.48016 0c-2.4505005 0 -4.4370728 -1.9865417 -4.4370728 -4.4370728z" fill-rule="evenodd"/><path fill="#4c1130" d="m633.7898 37.447086l0 -12.40625l2.34375 0l0 12.40625l-2.34375 0zm4.8339233 0l0 -8.84375l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.890625q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm9.428589 -6.890625l0 -1.953125l1.65625 0l0 1.953125l-1.65625 0zm1.578125 6.890625l0 -9.328125q0 -0.984375 0.40625 -1.703125q0.40625 -0.734375 1.140625 -1.125q0.734375 -0.390625 1.734375 -0.390625q0.359375 0 0.71875 0.0625q0.359375 0.046875 0.6875 0.125l0 2.21875q-0.296875 -0.140625 -0.578125 -0.203125q-0.265625 -0.078125 -0.546875 -0.078125q-0.59375 0 -0.953125 0.34375q-0.34375 0.34375 -0.34375 0.953125l0 9.125l-2.265625 0zm2.171875 -6.890625l0 -1.953125l2.265625 0l0 1.953125l-2.265625 0zm7.406128 7.171875q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.84375l2.125 0l0 1.1875l0.140625 0q0.234375 -0.421875 0.59375 -0.734375q0.375 -0.328125 0.875 -0.515625q0.515625 -0.1875 1.078125 -0.1875q0.34375 0 0.625 0.046875q0.28125 0.046875 0.484375 0.140625l0 2.265625q-0.359375 -0.140625 -0.71875 -0.234375q-0.359375 -0.09375 -0.75 -0.09375q-0.671875 0 -1.171875 0.34375q-0.5 0.328125 -0.765625 0.921875q-0.25 0.578125 -0.25 1.296875l0 4.40625l-2.265625 0zm11.089111 0.28125q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.84375l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.890625q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm14.501038 0.28125q-1.34375 0 -2.40625 -0.59375q-1.046875 -0.609375 -1.640625 -1.671875q-0.59375 -1.0625 -0.59375 -2.4375q0 -1.359375 0.59375 -2.421875q0.59375 -1.0625 1.640625 -1.65625q1.0625 -0.609375 2.40625 -0.609375q1.46875 0 2.53125 0.625q1.0625 0.625 1.53125 1.796875l-2.09375 0.859375q-0.265625 -0.59375 -0.78125 -0.875q-0.5 -0.296875 -1.1875 -0.296875q-0.671875 0 -1.21875 0.328125q-0.53125 0.3125 -0.84375 0.890625q-0.3125 0.5625 -0.3125 1.359375q0 0.796875 0.3125 1.390625q0.3125 0.578125 0.84375 0.90625q0.546875 0.3125 1.21875 0.3125q0.765625 0 1.265625 -0.34375q0.5 -0.34375 0.8125 -0.921875l2.03125 0.890625q-0.515625 1.109375 -1.578125 1.796875q-1.0625 0.671875 -2.53125 0.671875zm9.636047 0q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm6.291443 -0.28125l0 -12.40625l4.359375 0q1.203125 0 2.15625 0.5q0.953125 0.484375 1.515625 1.375q0.5625 0.875 0.5625 2.046875q0 1.15625 -0.5625 2.046875q-0.5625 0.890625 -1.515625 1.390625q-0.953125 0.484375 -2.15625 0.484375l-3.0625 0l0 -2.21875l3.140625 0q0.609375 0 1.015625 -0.234375q0.421875 -0.25 0.625 -0.640625q0.203125 -0.390625 0.203125 -0.828125q0 -0.453125 -0.203125 -0.828125q-0.203125 -0.390625 -0.625 -0.625q-0.40625 -0.25 -1.015625 -0.25l-2.09375 0l0 10.1875l-2.34375 0zm14.008362 0.28125q-1.375 0 -2.453125 -0.609375q-1.0625 -0.625 -1.65625 -1.6875q-0.59375 -1.0625 -0.59375 -2.40625q0 -1.328125 0.59375 -2.390625q0.59375 -1.078125 1.65625 -1.6875q1.078125 -0.609375 2.453125 -0.609375q1.390625 0 2.4375 0.625q1.0625 0.625 1.65625 1.6875q0.609375 1.046875 0.609375 2.375q0 1.34375 -0.609375 2.40625q-0.59375 1.0625 -1.65625 1.6875q-1.046875 0.609375 -2.4375 0.609375zm0 -2.125q0.671875 0 1.203125 -0.296875q0.546875 -0.296875 0.890625 -0.875q0.34375 -0.59375 0.34375 -1.40625q0 -0.8125 -0.34375 -1.375q-0.34375 -0.578125 -0.890625 -0.890625q-0.53125 -0.3125 -1.171875 -0.3125q-0.671875 0 -1.234375 0.3125q-0.5625 0.3125 -0.90625 0.890625q-0.328125 0.5625 -0.328125 1.375q0 0.8125 0.328125 1.40625q0.34375 0.578125 0.90625 0.875q0.5625 0.296875 1.203125 0.296875zm10.62207 2.125q-1.375 0 -2.453125 -0.609375q-1.0625 -0.625 -1.65625 -1.6875q-0.59375 -1.0625 -0.59375 -2.40625q0 -1.328125 0.59375 -2.390625q0.59375 -1.078125 1.65625 -1.6875q1.078125 -0.609375 2.453125 -0.609375q1.390625 0 2.4375 0.625q1.0625 0.625 1.65625 1.6875q0.609375 1.046875 0.609375 2.375q0 1.34375 -0.609375 2.40625q-0.59375 1.0625 -1.65625 1.6875q-1.046875 0.609375 -2.4375 0.609375zm0 -2.125q0.671875 0 1.203125 -0.296875q0.546875 -0.296875 0.890625 -0.875q0.34375 -0.59375 0.34375 -1.40625q0 -0.8125 -0.34375 -1.375q-0.34375 -0.578125 -0.890625 -0.890625q-0.53125 -0.3125 -1.171875 -0.3125q-0.671875 0 -1.234375 0.3125q-0.5625 0.3125 -0.90625 0.890625q-0.328125 0.5625 -0.328125 1.375q0 0.8125 0.328125 1.40625q0.34375 0.578125 0.90625 0.875q0.5625 0.296875 1.203125 0.296875zm6.4033813 1.84375l0 -12.40625l2.265625 0l0 12.40625l-2.265625 0z" fill-rule="nonzero"/><path fill="#4c1130" d="m639.2117 53.933964q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.44873 -2.015625q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm5.7299194 -4.9375l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm11.683105 5.125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.870544 3.890625q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.26123 0.171875q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm8.526794 -3.5625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm3.3706055 -3.59375l1.140625 0l0.03125 1.328125q0.640625 -0.765625 1.25 -1.109375q0.625 -0.34375 1.25 -0.34375q1.125 0 1.703125 0.71875q0.578125 0.71875 0.53125 2.15625l-1.265625 0q0.03125 -0.953125 -0.265625 -1.375q-0.296875 -0.421875 -0.875 -0.421875q-0.25 0 -0.515625 0.09375q-0.25 0.078125 -0.515625 0.28125q-0.265625 0.1875 -0.5625 0.5q-0.296875 0.3125 -0.640625 0.75l0 4.609375l-1.265625 0l0 -7.1875zm10.651794 -0.125q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm18.506775 5.0l-0.53125 0q-1.375 0 -2.0625 -0.65625q-0.671875 -0.640625 -0.671875 -1.953125l0 -2.46875q0 -0.34375 -0.078125 -0.625q-0.078125 -0.28125 -0.28125 -0.46875q-0.1875 -0.1875 -0.515625 -0.28125q-0.328125 -0.109375 -0.8125 -0.109375l-0.3125 0l0 -0.984375l0.3125 0q0.515625 0 0.84375 -0.078125q0.328125 -0.09375 0.515625 -0.265625q0.1875 -0.1875 0.25 -0.453125q0.078125 -0.28125 0.078125 -0.640625l0 -1.703125q0 -0.59375 0.140625 -1.078125q0.15625 -0.484375 0.46875 -0.828125q0.328125 -0.34375 0.84375 -0.515625q0.53125 -0.1875 1.28125 -0.1875l0.53125 0l0 1.0l-0.421875 0q-1.65625 0 -1.65625 1.609375l0 1.671875q0 1.734375 -1.515625 1.96875q1.515625 0.140625 1.515625 1.953125l0 2.453125q0 1.640625 1.65625 1.640625l0.421875 0l0 1.0zm8.91748 -6.65625q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm9.448669 0.015625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm9.339355 -0.0625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm5.5267944 -5.5l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm8.495605 1.78125q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.36615 -1.65625q0 0.890625 -0.25 1.59375q-0.234375 0.703125 -0.703125 1.203125q-0.453125 0.484375 -1.109375 0.75q-0.640625 0.25 -1.453125 0.25q-0.640625 0 -1.3125 -0.109375q-0.65625 -0.125 -1.3125 -0.390625l0 -9.6875l1.25 0l0 2.78125l-0.0625 1.328125q0.546875 -0.71875 1.15625 -1.015625q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.359375 0.140625 0.734375 0.234375q0.390625 0.078125 0.734375 0.078125q0.421875 0 0.8125 -0.125q0.390625 -0.140625 0.6875 -0.453125q0.296875 -0.328125 0.46875 -0.859375q0.1875 -0.53125 0.1875 -1.3125zm7.8080444 3.671875l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm9.26123 1.3125q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.448669 -2.015625q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.308105 0.84375l-4.28125 0l0 -1.171875l4.28125 0l0 1.171875zm8.151794 3.3125l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.19873 -3.65625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm2.7142944 0.15625q0 -0.921875 0.25 -1.625q0.25 -0.71875 0.703125 -1.203125q0.46875 -0.5 1.109375 -0.75q0.65625 -0.25 1.453125 -0.25q0.34375 0 0.671875 0.046875q0.328125 0.03125 0.65625 0.125l0 -3.015625l1.25 0l0 10.109375l-1.109375 0l-0.046875 -1.359375q-0.515625 0.765625 -1.125 1.125q-0.609375 0.359375 -1.328125 0.359375q-0.609375 0 -1.078125 -0.25q-0.46875 -0.265625 -0.78125 -0.734375q-0.3125 -0.46875 -0.46875 -1.125q-0.15625 -0.65625 -0.15625 -1.453125zm1.265625 -0.078125q0 1.296875 0.375 1.9375q0.390625 0.640625 1.09375 0.640625q0.484375 0 1.0 -0.421875q0.53125 -0.421875 1.109375 -1.25l0 -3.34375q-0.3125 -0.140625 -0.6875 -0.203125q-0.359375 -0.078125 -0.734375 -0.078125q-1.015625 0 -1.59375 0.65625q-0.5625 0.65625 -0.5625 2.0625zm13.22998 -0.453125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm5.7299194 -4.9375l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm6.1049805 -1.265625l0.53125 0q1.375 0 2.046875 0.65625q0.671875 0.640625 0.671875 1.953125l0 1.65625q0 0.34375 0.078125 0.625q0.078125 0.265625 0.28125 0.46875q0.203125 0.1875 0.53125 0.296875q0.328125 0.09375 0.8125 0.09375l0.3125 0l0 0.984375l-0.3125 0q-0.515625 0 -0.859375 0.09375q-0.328125 0.078125 -0.515625 0.265625q-0.1875 0.171875 -0.265625 0.4375q-0.0625 0.265625 -0.0625 0.640625l0 2.515625q0 0.59375 -0.140625 1.078125q-0.140625 0.484375 -0.46875 0.8125q-0.3125 0.34375 -0.84375 0.53125q-0.515625 0.1875 -1.265625 0.1875l-0.53125 0l0 -1.0l0.421875 0q1.65625 0 1.65625 -1.609375l0 -2.484375q0 -1.75 1.515625 -1.953125q-1.53125 -0.171875 -1.53125 -1.96875l0 -1.640625q0 -1.640625 -1.640625 -1.640625l-0.421875 0l0 -1.0z" fill-rule="nonzero"/><path fill="#c9daf8" d="m2.5485563 9.969208l0 0c0 -3.7881055 3.070866 -6.8589716 6.8589716 -6.8589716l190.84898 0c1.819107 0 3.5637207 0.72263956 4.8500214 2.0089464c1.2863159 1.2863064 2.0089417 3.0309124 2.0089417 4.850025l0 68.61276c0 3.7881088 -3.0708618 6.8589783 -6.858963 6.8589783l-190.84898 0l0 0c-3.7881055 0 -6.8589716 -3.0708694 -6.8589716 -6.8589783z" fill-rule="evenodd"/><path stroke="#a4c2f4" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m2.5485563 9.969208l0 0c0 -3.7881055 3.070866 -6.8589716 6.8589716 -6.8589716l190.84898 0c1.819107 0 3.5637207 0.72263956 4.8500214 2.0089464c1.2863159 1.2863064 2.0089417 3.0309124 2.0089417 4.850025l0 68.61276c0 3.7881088 -3.0708618 6.8589783 -6.858963 6.8589783l-190.84898 0l0 0c-3.7881055 0 -6.8589716 -3.0708694 -6.8589716 -6.8589783z" fill-rule="evenodd"/><path fill="#1c4587" d="m20.885605 32.69684q-1.328125 0 -2.515625 -0.484375q-1.1875 -0.484375 -2.109375 -1.34375q-0.90624905 -0.875 -1.421874 -2.0625q-0.5 -1.1875 -0.5 -2.59375q0 -1.40625 0.5 -2.59375q0.515625 -1.1875 1.421874 -2.046875q0.90625 -0.875 2.09375 -1.359375q1.1875 -0.484375 2.53125 -0.484375q1.484375 0 2.6875 0.53125q1.203125 0.515625 2.046875 1.4375l-1.609375 1.5625q-0.40625 -0.421875 -0.875 -0.703125q-0.46875 -0.296875 -1.03125 -0.453125q-0.546875 -0.15625 -1.234375 -0.15625q-0.84375 0 -1.609375 0.3125q-0.75 0.296875 -1.328125 0.859375q-0.578125 0.5625 -0.90625 1.34375q-0.328125 0.78125 -0.328125 1.75q0 0.96875 0.328125 1.75q0.328125 0.78125 0.90625 1.34375q0.578125 0.5625 1.34375 0.875q0.765625 0.296875 1.625 0.296875q0.875 0 1.546875 -0.234375q0.671875 -0.25 1.140625 -0.65625q0.484375 -0.421875 0.765625 -0.9375q0.296875 -0.515625 0.375 -1.046875l-3.890625 0l0 -2.0l6.078125 0q0.046875 0.171875 0.078125 0.53125q0.046875 0.34375 0.046875 0.5625l0 0l0 0l0 0q0 1.375 -0.46875 2.484375q-0.453125 1.109375 -1.28125 1.90625q-0.8125 0.78125 -1.953125 1.203125q-1.125 0.40625 -2.453125 0.40625zm10.485352 0q-0.9375 0 -1.65625 -0.375q-0.71875 -0.375 -1.140625 -1.046875q-0.40625 -0.671875 -0.40625 -1.5625q0 -0.921875 0.46875 -1.578125q0.484375 -0.65625 1.28125 -1.015625q0.8125 -0.375 1.796875 -0.375q0.546875 0 0.984375 0.0625q0.4375 0.0625 0.78125 0.15625q0.34375 0.078125 0.578125 0.1875l0 -0.390625q0 -0.703125 -0.546875 -1.15625q-0.53125 -0.46875 -1.46875 -0.46875q-0.625 0 -1.203125 0.296875q-0.578125 0.28125 -0.953125 0.75l-1.46875 -1.140625q0.4375 -0.5625 1.0 -0.953125q0.578125 -0.390625 1.265625 -0.578125q0.703125 -0.203125 1.46875 -0.203125q2.03125 0 3.078125 0.9375q1.0625 0.921875 1.0625 2.734375l0 5.4375l-2.234375 0l0 -0.90625l-0.140625 0q-0.25 0.3125 -0.609375 0.59375q-0.359375 0.265625 -0.84375 0.421875q-0.484375 0.171875 -1.09375 0.171875zm0.53125 -1.765625q0.703125 0 1.171875 -0.296875q0.484375 -0.3125 0.734375 -0.796875q0.25 -0.484375 0.25 -1.03125q-0.390625 -0.1875 -0.875 -0.296875q-0.484375 -0.109375 -0.984375 -0.109375q-1.0 0 -1.390625 0.390625q-0.375 0.375 -0.375 0.921875q0 0.515625 0.375 0.875q0.375 0.34375 1.09375 0.34375zm5.537445 -5.40625l0 -1.953125l1.625 0l0 1.953125l-1.625 0zm4.46875 7.03125q-1.375 0 -2.15625 -0.78125q-0.78125 -0.796875 -0.78125 -2.1875l0 -8.5l2.28125 0l0 8.09375q0 0.640625 0.25 0.9375q0.265625 0.296875 0.859375 0.296875q0.265625 0 0.5 -0.078125q0.25 -0.078125 0.625 -0.296875l0 2.21875q-0.390625 0.140625 -0.78125 0.21875q-0.390625 0.078125 -0.796875 0.078125zm-0.75 -7.03125l0 -1.953125l2.25 0l0 1.953125l-2.25 0zm7.8359222 7.171875q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm7.791443 -0.28125l-2.796875 -8.84375l2.546875 0l1.515625 5.734375l0.125 0l1.765625 -5.734375l2.328125 0l1.765625 5.734375l0.125 0l1.515625 -5.734375l2.515625 0l-2.828125 8.84375l-2.4375 0l-1.796875 -5.71875l-0.125 0l-1.78125 5.71875l-2.4375 0zm15.149826 0.28125q-0.9375 0 -1.65625 -0.375q-0.71875 -0.375 -1.140625 -1.046875q-0.40625 -0.671875 -0.40625 -1.5625q0 -0.921875 0.46875 -1.578125q0.484375 -0.65625 1.28125 -1.015625q0.8125 -0.375 1.796875 -0.375q0.546875 0 0.984375 0.0625q0.4375 0.0625 0.78125 0.15625q0.34375 0.078125 0.578125 0.1875l0 -0.390625q0 -0.703125 -0.546875 -1.15625q-0.53125 -0.46875 -1.46875 -0.46875q-0.625 0 -1.203125 0.296875q-0.578125 0.28125 -0.953125 0.75l-1.46875 -1.140625q0.4375 -0.5625 1.0 -0.953125q0.578125 -0.390625 1.265625 -0.578125q0.703125 -0.203125 1.46875 -0.203125q2.03125 0 3.078125 0.9375q1.0625 0.921875 1.0625 2.734375l0 5.4375l-2.234375 0l0 -0.90625l-0.140625 0q-0.25 0.3125 -0.609375 0.59375q-0.359375 0.265625 -0.84375 0.421875q-0.484375 0.171875 -1.09375 0.171875zm0.53125 -1.765625q0.703125 0 1.171875 -0.296875q0.484375 -0.3125 0.734375 -0.796875q0.25 -0.484375 0.25 -1.03125q-0.390625 -0.1875 -0.875 -0.296875q-0.484375 -0.109375 -0.984375 -0.109375q-1.0 0 -1.390625 0.390625q-0.375 0.375 -0.375 0.921875q0 0.515625 0.375 0.875q0.375 0.34375 1.09375 0.34375zm9.702225 4.828125q-0.046875 0.125 -0.09375 0.21875q-0.03125 0.09375 -0.078125 0.1875l-2.4375 0q0.0625 -0.140625 0.265625 -0.59375q0.203125 -0.4375 0.34375 -0.75q0.09375 -0.203125 0.234375 -0.53125q0.140625 -0.328125 0.28125 -0.65625q0.15625 -0.3125 0.25 -0.484375l1.328125 -2.96875l0.46875 -1.109375l2.203125 -5.5l2.53125 0l-4.5625 10.5q-0.1875 0.453125 -0.34375 0.78125q-0.140625 0.328125 -0.234375 0.546875q-0.078125 0.21875 -0.15625 0.359375zm-0.59375 -3.484375l-3.859375 -8.703125l2.59375 0l2.28125 5.5l0.265625 0l-1.28125 3.203125z" fill-rule="nonzero"/><path fill="#1c4587" d="m20.479355 50.855587l-1.25 0l0 -4.59375q0 -0.828125 -0.3125 -1.234375q-0.3125 -0.40625 -0.890625 -0.40625q-0.25 0 -0.46875 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.28125 0.28125 -0.64062405 0.71875l0 4.765625l-1.25 0l0 -10.109375l1.25 0l0 2.921875l-0.046875 1.140625q0.29687405 -0.359375 0.57812405 -0.59375q0.28125 -0.25 0.5625 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.078125 0 1.65625 0.65625q0.59375 0.65625 0.59375 1.96875l0 4.6875zm8.54245 -3.65625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.7612 1.640625q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.16745 1.859375q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm2.2612 -7.09375l1.109375 0l0.046875 1.15625q0.328125 -0.359375 0.609375 -0.609375q0.296875 -0.25 0.578125 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.109375 0 1.671875 0.65625q0.578125 0.65625 0.578125 1.96875l0 4.6875l-1.25 0l0 -4.59375q0 -0.84375 -0.3125 -1.234375q-0.3125 -0.40625 -0.9375 -0.40625q-0.234375 0 -0.453125 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.265625 0.28125 -0.609375 0.71875l0 4.765625l-1.25 0l0 -7.1875zm12.683075 7.1875l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm8.6987 3.265625l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0112 -3.96875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm6.16745 -3.15625q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.30365 -1.90625q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm9.7612 4.15625l-1.65625 0l-1.9375 -2.734375l-1.921875 2.734375l-1.609375 0l2.78125 -3.609375l-2.65625 -3.578125l1.59375 0l1.890625 2.765625l1.859375 -2.765625l1.53125 0l-2.6875 3.609375l2.8125 3.578125zm6.1987 0l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm8.6987 3.265625l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0737 -3.71875q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm5.6362 -5.421875l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm11.683075 5.125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm6.10495 1.90625q0.25 0 0.46875 0.09375q0.21875 0.09375 0.375 0.265625q0.15625 0.15625 0.25 0.375q0.09375 0.21875 0.09375 0.46875q0 0.234375 -0.09375 0.453125q-0.09375 0.21875 -0.25 0.375q-0.15625 0.15625 -0.375 0.25q-0.21875 0.09375 -0.46875 0.09375q-0.25 0 -0.46875 -0.09375q-0.203125 -0.09375 -0.375 -0.25q-0.15625 -0.15625 -0.25 -0.375q-0.09375 -0.21875 -0.09375 -0.453125q0 -0.25 0.09375 -0.46875q0.09375 -0.21875 0.25 -0.375q0.171875 -0.171875 0.375 -0.265625q0.21875 -0.09375 0.46875 -0.09375zm10.8237 1.984375q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.72995 -3.390625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.1987 3.59375l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0z" fill-rule="nonzero"/><path fill="#1c4587" d="m20.83873 65.13684q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.68749905 -0.125l0 3.015625l-1.25 0l0 -10.125004l1.109375 0l0.078125 1.203125q0.54687405 -0.734375 1.156249 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.6562538 0.15625 1.4687538zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.4687538 -0.265625 -0.7968788q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.60937405 0.7031288l0 3.484375q0.34374905 0.140625 0.71874905 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm9.4487 0.015625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.5312538q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875038 0.234375 1.5625038zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5000038 -0.421875 -0.8281288q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.8437538q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm3.370575 -3.5937538l1.140625 0l0.03125 1.328125q0.640625 -0.765625 1.25 -1.109375q0.625 -0.34375 1.25 -0.34375q1.125 0 1.703125 0.71875q0.578125 0.71875 0.53125 2.1562538l-1.265625 0q0.03125 -0.9531288 -0.265625 -1.3750038q-0.296875 -0.421875 -0.875 -0.421875q-0.25 0 -0.515625 0.09375q-0.25 0.078125 -0.515625 0.28125q-0.265625 0.1875 -0.5625 0.5q-0.296875 0.3125 -0.640625 0.7500038l0 4.609375l-1.265625 0l0 -7.187504zm13.558075 7.093754q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.7500038l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.6562538q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm5.151825 -7.218754q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.250004q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.756775 0l-1.59375 0l0 2.0625l-1.265625 0l0 -2.0625l-4.5 0l0 -1.09375l3.984375 -6.203129l1.78125 0l0 6.203129l1.59375 0l0 1.09375zm-2.859375 -6.093754l-3.265625 5.000004l3.265625 0l0 -5.000004zm10.91745 6.093754l-1.59375 0l0 2.0625l-1.265625 0l0 -2.0625l-4.5 0l0 -1.09375l3.984375 -6.203129l1.78125 0l0 6.203129l1.59375 0l0 1.09375zm-2.859375 -6.093754l-3.265625 5.000004l3.265625 0l0 -5.000004zm10.276825 5.312504q0 0.625 -0.25 1.171875q-0.25 0.53125 -0.75 0.9375q-0.5 0.390625 -1.265625 0.625q-0.75 0.234375 -1.765625 0.234375q-0.546875 0 -1.0 -0.03125q-0.4375 -0.03125 -0.828125 -0.09375l0 -1.109375q0.453125 0.078125 0.9375 0.125q0.5 0.03125 1.015625 0.03125q0.703125 0 1.1875 -0.125q0.5 -0.125 0.8125 -0.359375q0.328125 -0.234375 0.46875 -0.5625q0.140625 -0.34375 0.140625 -0.765625q0 -0.390625 -0.171875 -0.671875q-0.171875 -0.296875 -0.484375 -0.484375q-0.3125 -0.1875 -0.75 -0.28125q-0.421875 -0.109375 -0.9375 -0.109375l-1.078125 0l0 -1.0156288l1.09375 0q0.421875 0 0.765625 -0.109375q0.34375 -0.109375 0.59375 -0.3125q0.25 -0.21875 0.375 -0.515625q0.140625 -0.3125 0.140625 -0.703125q0 -0.75 -0.46875 -1.09375q-0.453125 -0.34375 -1.34375 -0.34375q-0.46875 0 -0.96875 0.09375q-0.5 0.09375 -1.078125 0.28125l0 -1.09375q0.25 -0.078125 0.515625 -0.140625q0.28125 -0.078125 0.546875 -0.125q0.28125 -0.046875 0.546875 -0.0625q0.28125 -0.03125 0.53125 -0.03125q0.75 0 1.3125 0.171875q0.5625 0.15625 0.9375 0.453125q0.390625 0.296875 0.578125 0.734375q0.1875 0.421875 0.1875 0.96875q0 0.796875 -0.40625 1.34375q-0.40625 0.53125 -1.125 0.859375q0.359375 0.0625 0.71875 0.23437881q0.359375 0.171875 0.640625 0.4375q0.28125 0.265625 0.453125 0.640625q0.171875 0.359375 0.171875 0.796875z" fill-rule="nonzero"/><path fill="#c9daf8" d="m0 6.858971l0 0c0 -3.788105 3.070866 -6.858971 6.858971 -6.858971l190.84898 0c1.819107 0 3.5637207 0.72263956 4.8500214 2.0089462c1.2863007 1.2863066 2.0089417 3.0309126 2.0089417 4.850025l0 68.61277c0 3.7881012 -3.0708618 6.8589706 -6.858963 6.8589706l-190.84898 0l0 0c-3.788105 0 -6.858971 -3.0708694 -6.858971 -6.8589706z" fill-rule="evenodd"/><path stroke="#a4c2f4" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m0 6.858971l0 0c0 -3.788105 3.070866 -6.858971 6.858971 -6.858971l190.84898 0c1.819107 0 3.5637207 0.72263956 4.8500214 2.0089462c1.2863007 1.2863066 2.0089417 3.0309126 2.0089417 4.850025l0 68.61277c0 3.7881012 -3.0708618 6.8589706 -6.858963 6.8589706l-190.84898 0l0 0c-3.788105 0 -6.858971 -3.0708694 -6.858971 -6.8589706z" fill-rule="evenodd"/><path fill="#1c4587" d="m18.33705 29.586603q-1.328125 0 -2.515625 -0.484375q-1.1875 -0.484375 -2.109375 -1.34375q-0.90625 -0.875 -1.421875 -2.0625q-0.5 -1.1875 -0.5 -2.59375q0 -1.40625 0.5 -2.59375q0.515625 -1.1875 1.421875 -2.046875q0.90625 -0.875 2.09375 -1.359375q1.1875 -0.484375 2.53125 -0.484375q1.484375 0 2.6875 0.53125q1.203125 0.515625 2.046875 1.4375l-1.609375 1.5625q-0.40625 -0.421875 -0.875 -0.703125q-0.46875 -0.296875 -1.03125 -0.453125q-0.546875 -0.15625 -1.234375 -0.15625q-0.84375 0 -1.609375 0.3125q-0.75 0.296875 -1.328125 0.859375q-0.578125 0.5625 -0.90625 1.34375q-0.328125 0.78125 -0.328125 1.75q0 0.96875 0.328125 1.75q0.328125 0.78125 0.90625 1.34375q0.578125 0.5625 1.34375 0.875q0.765625 0.296875 1.625 0.296875q0.875 0 1.546875 -0.234375q0.671875 -0.25 1.140625 -0.65625q0.484375 -0.421875 0.765625 -0.9375q0.296875 -0.515625 0.375 -1.046875l-3.890625 0l0 -2.0l6.078125 0q0.046875 0.171875 0.078125 0.53125q0.046875 0.34375 0.046875 0.5625l0 0l0 0l0 0q0 1.375 -0.46875 2.484375q-0.453125 1.109375 -1.28125 1.90625q-0.8125 0.78125 -1.953125 1.203125q-1.125 0.40625 -2.453125 0.40625zm10.485352 0q-0.9375 0 -1.65625 -0.375q-0.71875 -0.375 -1.140625 -1.046875q-0.40625 -0.671875 -0.40625 -1.5625q0 -0.921875 0.46875 -1.578125q0.484375 -0.65625 1.28125 -1.015625q0.8125 -0.375 1.796875 -0.375q0.546875 0 0.984375 0.0625q0.4375 0.0625 0.78125 0.15625q0.34375 0.078125 0.578125 0.1875l0 -0.390625q0 -0.703125 -0.546875 -1.15625q-0.53125 -0.46875 -1.46875 -0.46875q-0.625 0 -1.203125 0.296875q-0.578125 0.28125 -0.953125 0.75l-1.46875 -1.140625q0.4375 -0.5625 1.0 -0.953125q0.578125 -0.390625 1.265625 -0.578125q0.703125 -0.203125 1.46875 -0.203125q2.03125 0 3.078123 0.9375q1.0625 0.921875 1.0625 2.734375l0 5.4375l-2.234373 0l0 -0.90625l-0.140625 0q-0.25 0.3125 -0.609375 0.59375q-0.359375 0.265625 -0.84375 0.421875q-0.484375 0.171875 -1.09375 0.171875zm0.53125 -1.765625q0.703125 0 1.171875 -0.296875q0.484375 -0.3125 0.734375 -0.796875q0.25 -0.484375 0.25 -1.03125q-0.390625 -0.1875 -0.875 -0.296875q-0.484375 -0.109375 -0.984375 -0.109375q-1.0 0 -1.390625 0.390625q-0.375 0.375 -0.375 0.921875q0 0.515625 0.375 0.875q0.375 0.34375 1.09375 0.34375zm5.537443 -5.40625l0 -1.953125l1.625 0l0 1.953125l-1.625 0zm4.46875 7.03125q-1.375 0 -2.15625 -0.78125q-0.78125 -0.796875 -0.78125 -2.1875l0 -8.5l2.28125 0l0 8.09375q0 0.640625 0.25 0.9375q0.265625 0.296875 0.859375 0.296875q0.265625 0 0.5 -0.078125q0.25 -0.078125 0.625 -0.296875l0 2.21875q-0.390625 0.140625 -0.78125 0.21875q-0.390625 0.078125 -0.796875 0.078125zm-0.75 -7.03125l0 -1.953125l2.25 0l0 1.953125l-2.25 0zm7.8359222 7.171875q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm7.791443 -0.28125l-2.796875 -8.84375l2.546875 0l1.515625 5.734375l0.125 0l1.765625 -5.734375l2.328125 0l1.765625 5.734375l0.125 0l1.515625 -5.734375l2.5156288 0l-2.8281288 8.84375l-2.4375 0l-1.796875 -5.71875l-0.125 0l-1.78125 5.71875l-2.4375 0zm15.14983 0.28125q-0.9375 0 -1.65625 -0.375q-0.71875 -0.375 -1.140625 -1.046875q-0.40625 -0.671875 -0.40625 -1.5625q0 -0.921875 0.46875 -1.578125q0.484375 -0.65625 1.28125 -1.015625q0.8125 -0.375 1.796875 -0.375q0.546875 0 0.984375 0.0625q0.4375 0.0625 0.78125 0.15625q0.34375 0.078125 0.578125 0.1875l0 -0.390625q0 -0.703125 -0.546875 -1.15625q-0.53125 -0.46875 -1.46875 -0.46875q-0.625 0 -1.203125 0.296875q-0.578125 0.28125 -0.953125 0.75l-1.46875 -1.140625q0.4375 -0.5625 1.0 -0.953125q0.578125 -0.390625 1.265625 -0.578125q0.703125 -0.203125 1.46875 -0.203125q2.03125 0 3.078125 0.9375q1.0625 0.921875 1.0625 2.734375l0 5.4375l-2.234375 0l0 -0.90625l-0.140625 0q-0.25 0.3125 -0.609375 0.59375q-0.359375 0.265625 -0.84375 0.421875q-0.484375 0.171875 -1.09375 0.171875zm0.53125 -1.765625q0.703125 0 1.171875 -0.296875q0.484375 -0.3125 0.734375 -0.796875q0.25 -0.484375 0.25 -1.03125q-0.390625 -0.1875 -0.875 -0.296875q-0.484375 -0.109375 -0.984375 -0.109375q-1.0 0 -1.390625 0.390625q-0.375 0.375 -0.375 0.921875q0 0.515625 0.375 0.875q0.375 0.34375 1.09375 0.34375zm9.702225 4.828123q-0.046875 0.125 -0.09375 0.21875q-0.03125 0.09375 -0.078125 0.1875l-2.4375 0q0.0625 -0.140625 0.265625 -0.59375q0.203125 -0.4375 0.34375 -0.7499981q0.09375 -0.203125 0.234375 -0.53125q0.140625 -0.328125 0.28125 -0.65625q0.15625 -0.3125 0.25 -0.484375l1.328125 -2.96875l0.46875 -1.109375l2.203125 -5.5l2.53125 0l-4.5625 10.5q-0.1875 0.453125 -0.34375 0.78125q-0.140625 0.3281231 -0.234375 0.5468731q-0.078125 0.21875 -0.15625 0.359375zm-0.59375 -3.484373l-3.859375 -8.703125l2.59375 0l2.28125 5.5l0.265625 0l-1.28125 3.203125z" fill-rule="nonzero"/><path fill="#1c4587" d="m17.9308 47.74535l-1.25 0l0 -4.59375q0 -0.828125 -0.3125 -1.234375q-0.3125 -0.40625 -0.890625 -0.40625q-0.25 0 -0.46875 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.28125 0.28125 -0.640625 0.71875l0 4.765625l-1.25 0l0 -10.109375l1.25 0l0 2.921875l-0.046875 1.140625q0.296875 -0.359375 0.578125 -0.59375q0.28125 -0.25 0.5625 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.078125 0 1.65625 0.65625q0.59375 0.65625 0.59375 1.96875l0 4.6875zm8.54245 -3.65625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.761198 1.640625q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6874981 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3124981 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.5468731 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9374981 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.5312481 -0.078125 -0.9062481 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.6406231 0.1875 1.0624981 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.16745 1.859375q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm2.2612 -7.09375l1.109375 0l0.046875 1.15625q0.328125 -0.359375 0.609375 -0.609375q0.296875 -0.25 0.578125 -0.390625q0.28125 -0.15625 0.578125 -0.21875q0.296875 -0.0625 0.609375 -0.0625q1.109375 0 1.671875 0.65625q0.578125 0.65625 0.578125 1.96875l0 4.6875l-1.25 0l0 -4.59375q0 -0.84375 -0.3125 -1.234375q-0.3125 -0.40625 -0.9375 -0.40625q-0.234375 0 -0.453125 0.0625q-0.21875 0.0625 -0.453125 0.234375q-0.234375 0.171875 -0.515625 0.453125q-0.265625 0.28125 -0.609375 0.71875l0 4.765625l-1.25 0l0 -7.1875zm12.683075 7.1875l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm8.698704 3.265625l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.3906288 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.3281288 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0112 -3.96875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm6.16745 -3.15625q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm19.30365 -1.90625q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm9.7612 4.15625l-1.65625 0l-1.9375 -2.734375l-1.921875 2.734375l-1.609375 0l2.78125 -3.609375l-2.65625 -3.578125l1.59375 0l1.890625 2.765625l1.859375 -2.765625l1.53125 0l-2.6875 3.609375l2.8125 3.578125zm6.1987 0l-0.03125 -0.96875q-0.59375 0.578125 -1.203125 0.84375q-0.59375 0.25 -1.265625 0.25q-0.609375 0 -1.046875 -0.15625q-0.4375 -0.15625 -0.71875 -0.421875q-0.28125 -0.28125 -0.421875 -0.65625q-0.125 -0.375 -0.125 -0.8125q0 -1.078125 0.796875 -1.6875q0.8125 -0.609375 2.390625 -0.609375l1.484375 0l0 -0.640625q0 -0.625 -0.40625 -1.0q-0.40625 -0.390625 -1.25 -0.390625q-0.609375 0 -1.203125 0.140625q-0.578125 0.125 -1.21875 0.375l0 -1.125q0.25 -0.078125 0.53125 -0.15625q0.296875 -0.09375 0.609375 -0.15625q0.328125 -0.0625 0.671875 -0.09375q0.359375 -0.046875 0.71875 -0.046875q0.640625 0 1.15625 0.140625q0.53125 0.140625 0.890625 0.4375q0.359375 0.296875 0.546875 0.75q0.203125 0.4375 0.203125 1.03125l0 4.953125l-1.109375 0zm-0.140625 -3.265625l-1.578125 0q-0.46875 0 -0.8125 0.09375q-0.328125 0.09375 -0.546875 0.265625q-0.21875 0.171875 -0.328125 0.40625q-0.09375 0.234375 -0.09375 0.546875q0 0.203125 0.0625 0.390625q0.0625 0.1875 0.203125 0.34375q0.15625 0.140625 0.375 0.234375q0.234375 0.078125 0.5625 0.078125q0.4375 0 0.984375 -0.265625q0.5625 -0.265625 1.171875 -0.828125l0 -1.265625zm8.6987 3.265625l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0zm9.0737 -3.71875q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm5.6362 -5.421875l-2.125 0l0 -1.015625l3.390625 0l0 9.078125l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -8.0625zm11.683075 5.125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm6.10495 1.90625q0.25 0 0.46875 0.09375q0.21875 0.09375 0.375 0.265625q0.15625 0.15625 0.25 0.375q0.09375 0.21875 0.09375 0.46875q0 0.234375 -0.09375 0.453125q-0.09375 0.21875 -0.25 0.375q-0.15625 0.15625 -0.375 0.25q-0.21875 0.09375 -0.46875 0.09375q-0.25 0 -0.46875 -0.09375q-0.203125 -0.09375 -0.375 -0.25q-0.15625 -0.15625 -0.25 -0.375q-0.09375 -0.21875 -0.09375 -0.453125q0 -0.25 0.09375 -0.46875q0.09375 -0.21875 0.25 -0.375q0.171875 -0.171875 0.375 -0.265625q0.21875 -0.09375 0.46875 -0.09375zm10.8237 1.984375q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.72995 -3.390625q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm8.1987 3.59375l0 -5.15625q0 -0.34375 -0.03125 -0.546875q-0.015625 -0.21875 -0.078125 -0.34375q-0.046875 -0.125 -0.125 -0.171875q-0.078125 -0.0625 -0.203125 -0.0625q-0.140625 0 -0.265625 0.09375q-0.125 0.078125 -0.265625 0.28125q-0.140625 0.1875 -0.3125 0.515625q-0.15625 0.3125 -0.390625 0.78125l0 4.609375l-1.140625 0l0 -5.03125q0 -0.390625 -0.03125 -0.625q-0.015625 -0.25 -0.078125 -0.375q-0.046875 -0.140625 -0.140625 -0.1875q-0.078125 -0.0625 -0.203125 -0.0625q-0.125 0 -0.25 0.078125q-0.109375 0.0625 -0.25 0.25q-0.125 0.1875 -0.296875 0.515625q-0.171875 0.328125 -0.40625 0.828125l0 4.609375l-1.15625 0l0 -7.1875l0.953125 0l0.0625 1.375q0.1875 -0.40625 0.359375 -0.6875q0.171875 -0.296875 0.359375 -0.46875q0.1875 -0.1875 0.390625 -0.265625q0.21875 -0.078125 0.46875 -0.078125q0.59375 0 0.890625 0.375q0.296875 0.375 0.296875 1.171875q0.171875 -0.375 0.328125 -0.65625q0.171875 -0.296875 0.359375 -0.484375q0.1875 -0.203125 0.421875 -0.296875q0.234375 -0.109375 0.53125 -0.109375q1.34375 0 1.34375 2.078125l0 5.234375l-1.140625 0z" fill-rule="nonzero"/><path fill="#1c4587" d="m18.290174 62.0266q0 0.953125 -0.265625 1.671875q-0.265625 0.7187538 -0.75 1.1875038q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125004l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.4843788q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875038 0.578125 -2.0625038zm9.4487 0.015625q0 0.84375 -0.25 1.546875q-0.234375 0.6875038 -0.671875 1.1875038q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.1562538q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.8281288q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.3750038 0.375 -0.8593788q0.125 -0.484375 0.125 -1.015625zm3.370575 -3.59375l1.140625 0l0.03125 1.328125q0.640625 -0.765625 1.25 -1.109375q0.625 -0.34375 1.2499981 -0.34375q1.125 0 1.703125 0.71875q0.578125 0.71875 0.53125 2.15625l-1.265625 0q0.03125 -0.953125 -0.265625 -1.375q-0.296875 -0.421875 -0.875 -0.421875q-0.2499981 0 -0.5156231 0.09375q-0.25 0.078125 -0.515625 0.28125q-0.265625 0.1875 -0.5625 0.5q-0.296875 0.3125 -0.640625 0.75l0 4.609379l-1.265625 0l0 -7.187504zm13.558073 7.093754q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.8750038l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.7656288 0.40625 1.1562538q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm5.151825 -7.218754q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.234375q0.15625 0.15625 0.234375 0.359375q0.09375 0.1875 0.09375 0.40625q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.15625 -0.34375 0.25q-0.203125 0.078125 -0.421875 0.078125q-0.234375 0 -0.4375 -0.078125q-0.1875 -0.09375 -0.34375 -0.25q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.40625q0.09375 -0.203125 0.234375 -0.359375q0.15625 -0.15625 0.34375 -0.234375q0.203125 -0.09375 0.4375 -0.09375zm0 5.25q0.21875 0 0.421875 0.09375q0.203125 0.078125 0.34375 0.23437881q0.15625 0.140625 0.234375 0.34375q0.09375 0.203125 0.09375 0.421875q0 0.234375 -0.09375 0.4375q-0.078125 0.1875 -0.234375 0.34375q-0.140625 0.140625 -0.34375 0.21875q-0.203125 0.09375 -0.421875 0.09375q-0.234375 0 -0.4375 -0.09375q-0.1875 -0.078125 -0.34375 -0.21875q-0.140625 -0.15625 -0.234375 -0.34375q-0.078125 -0.203125 -0.078125 -0.4375q0 -0.21875 0.078125 -0.421875q0.09375 -0.203125 0.234375 -0.34375q0.15625 -0.15625381 0.34375 -0.23437881q0.203125 -0.09375 0.4375 -0.09375zm19.756779 0l-1.59375 0l0 2.0625038l-1.265625 0l0 -2.0625038l-4.500004 0l0 -1.09375l3.984375 -6.203125l1.7812538 0l0 6.203125l1.59375 0l0 1.09375zm-2.859375 -6.09375l-3.2656288 5.0l3.2656288 0l0 -5.0zm10.91745 6.09375l-1.59375 0l0 2.0625038l-1.265625 0l0 -2.0625038l-4.5 0l0 -1.09375l3.984375 -6.203125l1.78125 0l0 6.203125l1.59375 0l0 1.09375zm-2.859375 -6.09375l-3.265625 5.0l3.265625 0l0 -5.0zm10.276825 5.3125q0 0.625 -0.25 1.1718788q-0.25 0.53125 -0.75 0.9375q-0.5 0.390625 -1.265625 0.625q-0.75 0.234375 -1.765625 0.234375q-0.546875 0 -1.0 -0.03125q-0.4375 -0.03125 -0.828125 -0.09375l0 -1.109375q0.453125 0.078125 0.9375 0.125q0.5 0.03125 1.015625 0.03125q0.703125 0 1.1875 -0.125q0.5 -0.125 0.8125 -0.359375q0.328125 -0.234375 0.46875 -0.5625038q0.140625 -0.34375 0.140625 -0.765625q0 -0.390625 -0.171875 -0.671875q-0.171875 -0.296875 -0.484375 -0.484375q-0.3125 -0.1875 -0.75 -0.28125q-0.421875 -0.109375 -0.9375 -0.109375l-1.078125 0l0 -1.015625l1.09375 0q0.421875 0 0.765625 -0.109375q0.34375 -0.109375 0.59375 -0.3125q0.25 -0.21875 0.375 -0.515625q0.140625 -0.3125 0.140625 -0.703125q0 -0.75 -0.46875 -1.09375q-0.453125 -0.34375 -1.34375 -0.34375q-0.46875 0 -0.96875 0.09375q-0.5 0.09375 -1.078125 0.28125l0 -1.09375q0.25 -0.078125 0.515625 -0.140625q0.28125 -0.078125 0.546875 -0.125q0.28125 -0.046875 0.546875 -0.0625q0.28125 -0.03125 0.53125 -0.03125q0.75 0 1.3125 0.171875q0.5625 0.15625 0.9375 0.453125q0.390625 0.296875 0.578125 0.734375q0.1875 0.421875 0.1875 0.96875q0 0.796875 -0.40625 1.34375q-0.40625 0.53125 -1.125 0.859375q0.359375 0.0625 0.71875 0.234375q0.359375 0.171875 0.640625 0.4375q0.28125 0.265625 0.453125 0.640625q0.171875 0.359375 0.171875 0.796875z" fill-rule="nonzero"/><path fill="#d9d2e9" d="m646.47766 133.54955l0 0c0 -3.2214813 2.6115723 -5.833008 5.833069 -5.833008l192.90088 0c1.5469971 0 3.0306396 0.6145477 4.1245728 1.7084503c1.0938721 1.0939026 1.708435 2.5775452 1.708435 4.1245575l0 58.34973c0 3.2214813 -2.6115112 5.833008 -5.833008 5.833008l-192.90088 0c-3.2214966 0 -5.833069 -2.6115265 -5.833069 -5.833008z" fill-rule="evenodd"/><path stroke="#b4a7d6" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m646.47766 133.54955l0 0c0 -3.2214813 2.6115723 -5.833008 5.833069 -5.833008l192.90088 0c1.5469971 0 3.0306396 0.6145477 4.1245728 1.7084503c1.0938721 1.0939026 1.708435 2.5775452 1.708435 4.1245575l0 58.34973c0 3.2214813 -2.6115112 5.833008 -5.833008 5.833008l-192.90088 0c-3.2214966 0 -5.833069 -2.6115265 -5.833069 -5.833008z" fill-rule="evenodd"/><path fill="#20124d" d="m658.59235 150.86441l0 -12.40625l2.34375 0l0 12.40625l-2.34375 0zm4.8339233 0l0 -8.84375l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.890625q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm9.428589 -6.890625l0 -1.953125l1.65625 0l0 1.953125l-1.65625 0zm1.578125 6.890625l0 -9.328125q0 -0.984375 0.40625 -1.703125q0.40625 -0.734375 1.140625 -1.125q0.734375 -0.390625 1.734375 -0.390625q0.359375 0 0.71875 0.0625q0.359375 0.046875 0.6875 0.125l0 2.21875q-0.296875 -0.140625 -0.578125 -0.203125q-0.265625 -0.078125 -0.546875 -0.078125q-0.59375 0 -0.953125 0.34375q-0.34375 0.34375 -0.34375 0.953125l0 9.125l-2.265625 0zm2.171875 -6.890625l0 -1.953125l2.265625 0l0 1.953125l-2.265625 0zm7.406128 7.171875q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.84375l2.125 0l0 1.1875l0.140625 0q0.234375 -0.421875 0.59375 -0.734375q0.375 -0.328125 0.875 -0.515625q0.515625 -0.1875 1.078125 -0.1875q0.34375 0 0.625 0.046875q0.28125 0.046875 0.484375 0.140625l0 2.265625q-0.359375 -0.140625 -0.71875 -0.234375q-0.359375 -0.09375 -0.75 -0.09375q-0.671875 0 -1.171875 0.34375q-0.5 0.328125 -0.765625 0.921875q-0.25 0.578125 -0.25 1.296875l0 4.40625l-2.265625 0zm11.089111 0.28125q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm5.978943 -0.28125l0 -8.84375l2.125 0l0 1.109375l0.140625 0q0.40625 -0.640625 1.125 -1.0q0.734375 -0.375 1.578125 -0.375q1.625 0 2.4375 0.984375q0.828125 0.984375 0.828125 2.625l0 5.5l-2.28125 0l0 -5.21875q0 -0.859375 -0.4375 -1.3125q-0.4375 -0.46875 -1.203125 -0.46875q-0.625 0 -1.09375 0.34375q-0.453125 0.328125 -0.703125 0.890625q-0.25 0.5625 -0.25 1.265625l0 4.5l-2.265625 0zm14.501038 0.28125q-1.34375 0 -2.40625 -0.59375q-1.046875 -0.609375 -1.640625 -1.671875q-0.59375 -1.0625 -0.59375 -2.4375q0 -1.359375 0.59375 -2.421875q0.59375 -1.0625 1.640625 -1.65625q1.0625 -0.609375 2.40625 -0.609375q1.46875 0 2.53125 0.625q1.0625 0.625 1.53125 1.796875l-2.09375 0.859375q-0.265625 -0.59375 -0.78125 -0.875q-0.5 -0.296875 -1.1875 -0.296875q-0.671875 0 -1.21875 0.328125q-0.53125 0.3125 -0.84375 0.890625q-0.3125 0.5625 -0.3125 1.359375q0 0.796875 0.3125 1.390625q0.3125 0.578125 0.84375 0.90625q0.546875 0.3125 1.21875 0.3125q0.765625 0 1.265625 -0.34375q0.5 -0.34375 0.8125 -0.921875l2.03125 0.890625q-0.515625 1.109375 -1.578125 1.796875q-1.0625 0.671875 -2.53125 0.671875zm9.636047 0q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm12.150818 0q-1.390625 0 -2.578125 -0.484375q-1.1875 -0.5 -2.0625 -1.390625q-0.875 -0.90625 -1.359375 -2.078125q-0.484375 -1.1875 -0.484375 -2.53125q0 -1.359375 0.484375 -2.53125q0.484375 -1.171875 1.359375 -2.0625q0.875 -0.90625 2.0625 -1.390625q1.1875 -0.5 2.578125 -0.5q1.375 0 2.546875 0.5q1.1875 0.484375 2.0625 1.390625q0.890625 0.890625 1.375 2.0625q0.484375 1.171875 0.484375 2.53125q0 1.34375 -0.484375 2.53125q-0.484375 1.171875 -1.375 2.078125q-0.875 0.890625 -2.0625 1.390625q-1.171875 0.484375 -2.546875 0.484375zm0 -2.21875q1.15625 0 2.09375 -0.53125q0.9375 -0.546875 1.484375 -1.5q0.5625 -0.96875 0.5625 -2.234375q0 -1.28125 -0.5625 -2.234375q-0.546875 -0.953125 -1.484375 -1.484375q-0.9375 -0.546875 -2.09375 -0.546875q-1.15625 0 -2.09375 0.546875q-0.921875 0.53125 -1.484375 1.484375q-0.546875 0.953125 -0.546875 2.234375q0 1.265625 0.546875 2.234375q0.5625 0.953125 1.484375 1.5q0.9375 0.53125 2.09375 0.53125zm13.270874 2.21875q-0.640625 0 -1.171875 -0.203125q-0.515625 -0.1875 -0.890625 -0.484375q-0.359375 -0.296875 -0.59375 -0.65625l-0.140625 0l0 1.0625l-2.125 0l0 -12.40625l2.265625 0l0 3.390625l-0.140625 1.25l0.140625 0q0.234375 -0.34375 0.59375 -0.65625q0.375 -0.3125 0.890625 -0.5q0.53125 -0.1875 1.171875 -0.1875q1.203125 0 2.171875 0.59375q0.96875 0.59375 1.53125 1.65625q0.5625 1.046875 0.5625 2.4375q0 1.390625 -0.5625 2.453125q-0.5625 1.046875 -1.53125 1.65625q-0.96875 0.59375 -2.171875 0.59375zm-0.40625 -2.09375q0.640625 0 1.1875 -0.3125q0.546875 -0.328125 0.875 -0.921875q0.34375 -0.59375 0.34375 -1.375q0 -0.796875 -0.34375 -1.359375q-0.328125 -0.578125 -0.875 -0.890625q-0.546875 -0.328125 -1.1875 -0.328125q-0.625 0 -1.171875 0.328125q-0.53125 0.3125 -0.875 0.890625q-0.34375 0.578125 -0.34375 1.359375q0 0.78125 0.34375 1.359375q0.34375 0.578125 0.875 0.921875q0.546875 0.328125 1.171875 0.328125zm5.850769 5.734375q-0.328125 0 -0.59375 -0.03125q-0.28125 -0.03125 -0.59375 -0.09375l0 -2.203125q0.1875 0.109375 0.421875 0.171875q0.234375 0.078125 0.5 0.078125q0.421875 0 0.59375 -0.265625q0.1875 -0.265625 0.1875 -0.765625l0 -9.65625l2.265625 0l0 9.703125q0 1.109375 -0.390625 1.78125q-0.375 0.671875 -1.015625 0.96875q-0.625 0.3125 -1.375 0.3125zm1.65625 -13.734375q-0.609375 0 -1.046875 -0.421875q-0.421875 -0.4375 -0.421875 -1.046875q0 -0.609375 0.421875 -1.03125q0.4375 -0.421875 1.046875 -0.421875q0.609375 0 1.03125 0.421875q0.421875 0.421875 0.421875 1.03125q0 0.609375 -0.421875 1.046875q-0.421875 0.421875 -1.03125 0.421875zm7.453308 10.09375q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625zm10.135193 0q-1.34375 0 -2.40625 -0.59375q-1.046875 -0.609375 -1.640625 -1.671875q-0.59375 -1.0625 -0.59375 -2.4375q0 -1.359375 0.59375 -2.421875q0.59375 -1.0625 1.640625 -1.65625q1.0625 -0.609375 2.40625 -0.609375q1.46875 0 2.53125 0.625q1.0625 0.625 1.53125 1.796875l-2.09375 0.859375q-0.265625 -0.59375 -0.78125 -0.875q-0.5 -0.296875 -1.1875 -0.296875q-0.671875 0 -1.21875 0.328125q-0.53125 0.3125 -0.84375 0.890625q-0.3125 0.5625 -0.3125 1.359375q0 0.796875 0.3125 1.390625q0.3125 0.578125 0.84375 0.90625q0.546875 0.3125 1.21875 0.3125q0.765625 0 1.265625 -0.34375q0.5 -0.34375 0.8125 -0.921875l2.03125 0.890625q-0.515625 1.109375 -1.578125 1.796875q-1.0625 0.671875 -2.53125 0.671875zm4.8391724 -7.171875l0 -1.953125l1.625 0l0 1.953125l-1.625 0zm4.46875 7.03125q-1.375 0 -2.15625 -0.78125q-0.78125 -0.796875 -0.78125 -2.1875l0 -8.5l2.28125 0l0 8.09375q0 0.640625 0.25 0.9375q0.265625 0.296875 0.859375 0.296875q0.265625 0 0.5 -0.078125q0.25 -0.078125 0.625 -0.296875l0 2.21875q-0.390625 0.140625 -0.78125 0.21875q-0.390625 0.078125 -0.796875 0.078125zm-0.75 -7.03125l0 -1.953125l2.25 0l0 1.953125l-2.25 0zm4.128601 6.890625l0 -8.84375l2.265625 0l0 8.84375l-2.265625 0zm1.140625 -9.8125q-0.609375 0 -1.046875 -0.421875q-0.421875 -0.4375 -0.421875 -1.046875q0 -0.609375 0.421875 -1.03125q0.4375 -0.421875 1.046875 -0.421875q0.609375 0 1.03125 0.421875q0.421875 0.421875 0.421875 1.03125q0 0.609375 -0.421875 1.046875q-0.421875 0.421875 -1.03125 0.421875zm6.031433 9.8125l-3.75 -8.84375l2.59375 0l2.234375 5.765625l0.140625 0l2.265625 -5.765625l2.546875 0l-3.78125 8.84375l-2.25 0zm10.986877 0.28125q-1.328125 0 -2.390625 -0.609375q-1.046875 -0.609375 -1.640625 -1.65625q-0.59375 -1.0625 -0.59375 -2.421875q0 -1.265625 0.578125 -2.328125q0.59375 -1.078125 1.609375 -1.71875q1.03125 -0.65625 2.34375 -0.65625q1.421875 0 2.390625 0.609375q0.984375 0.59375 1.484375 1.609375q0.5 1.015625 0.5 2.25q0 0.28125 -0.015625 0.484375q-0.015625 0.1875 -0.03125 0.28125l-7.59375 0l0 -1.625l5.453125 0q-0.015625 -0.28125 -0.171875 -0.59375q-0.15625 -0.3125 -0.4375 -0.578125q-0.265625 -0.265625 -0.65625 -0.421875q-0.390625 -0.171875 -0.90625 -0.171875q-0.65625 0 -1.203125 0.359375q-0.546875 0.34375 -0.859375 0.953125q-0.296875 0.609375 -0.296875 1.46875q0 0.875 0.328125 1.5q0.328125 0.609375 0.890625 0.9375q0.5625 0.3125 1.25 0.3125q0.8125 0 1.359375 -0.34375q0.5625 -0.359375 0.875 -0.90625l1.84375 0.90625q-0.625 1.09375 -1.640625 1.734375q-1.0 0.625 -2.46875 0.625z" fill-rule="nonzero"/><path fill="#20124d" d="m664.7017 169.30441l-1.4375 0l-1.390625 -2.984375q-0.15625 -0.34375 -0.328125 -0.5625q-0.15625 -0.234375 -0.34375 -0.359375q-0.1875 -0.140625 -0.421875 -0.203125q-0.21875 -0.0625 -0.5 -0.0625l-0.609375 0l0 4.171875l-1.265625 0l0 -9.359375l2.5 0q0.8125 0 1.390625 0.1875q0.59375 0.171875 0.96875 0.5q0.390625 0.328125 0.5625 0.78125q0.171875 0.453125 0.171875 1.0q0 0.4375 -0.125 0.828125q-0.125 0.390625 -0.390625 0.71875q-0.25 0.3125 -0.625 0.546875q-0.375 0.21875 -0.859375 0.34375q0.390625 0.125 0.65625 0.46875q0.28125 0.34375 0.578125 0.90625l1.46875 3.078125zm-2.03125 -6.78125q0 -0.75 -0.46875 -1.125q-0.46875 -0.375 -1.328125 -0.375l-1.203125 0l0 3.09375l1.03125 0q0.453125 0 0.8125 -0.09375q0.359375 -0.109375 0.609375 -0.3125q0.265625 -0.203125 0.40625 -0.5q0.140625 -0.296875 0.140625 -0.6875zm9.79248 2.8125q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm2.9174194 0.71875q0 -0.78125 0.203125 -1.46875q0.203125 -0.703125 0.625 -1.21875q0.4375 -0.53125 1.09375 -0.828125q0.671875 -0.3125 1.59375 -0.3125q0.359375 0 0.71875 0.0625q0.359375 0.046875 0.765625 0.171875l1.09375 -0.28125l0 10.25l-1.25 0l0 -2.71875l0.0625 -1.53125q-1.015625 1.4375 -2.421875 1.4375q-0.625 0 -1.09375 -0.25q-0.46875 -0.265625 -0.78125 -0.734375q-0.296875 -0.46875 -0.453125 -1.125q-0.15625 -0.65625 -0.15625 -1.453125zm1.265625 -0.078125q0 0.59375 0.09375 1.078125q0.09375 0.484375 0.265625 0.8125q0.1875 0.328125 0.46875 0.515625q0.28125 0.171875 0.640625 0.171875q0.484375 0 1.0 -0.421875q0.53125 -0.421875 1.109375 -1.25l0 -3.34375q-0.28125 -0.125 -0.65625 -0.203125q-0.359375 -0.09375 -0.765625 -0.09375q-1.046875 0 -1.609375 0.703125q-0.546875 0.6875 -0.546875 2.03125zm12.933105 3.515625l-1.125 0l-0.03125 -1.15625q-0.328125 0.375 -0.625 0.625q-0.28125 0.234375 -0.578125 0.390625q-0.28125 0.140625 -0.578125 0.203125q-0.28125 0.0625 -0.59375 0.0625q-1.109375 0 -1.6875 -0.640625q-0.5625 -0.65625 -0.5625 -1.96875l0 -4.703125l1.25 0l0 4.59375q0 1.65625 1.25 1.65625q0.21875 0 0.4375 -0.0625q0.21875 -0.078125 0.453125 -0.234375q0.25 -0.171875 0.515625 -0.453125q0.28125 -0.296875 0.625 -0.734375l0 -4.765625l1.25 0l0 7.1875zm8.354919 -3.96875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.964355 2.203125q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.167419 1.859375q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm7.2924805 -3.21875l-4.28125 0l0 -1.171875l4.28125 0l0 1.171875zm8.714294 1.359375q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875zm8.51123 -1.765625q0 0.953125 -0.265625 1.671875q-0.265625 0.71875 -0.75 1.1875q-0.46875 0.46875 -1.109375 0.703125q-0.640625 0.234375 -1.390625 0.234375q-0.34375 0 -0.6875 -0.03125q-0.34375 -0.03125 -0.6875 -0.125l0 3.015625l-1.25 0l0 -10.125l1.109375 0l0.078125 1.203125q0.546875 -0.734375 1.15625 -1.03125q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.34375 0.140625 0.71875 0.234375q0.390625 0.078125 0.75 0.078125q1.0 0 1.578125 -0.6875q0.578125 -0.6875 0.578125 -2.0625zm9.261169 -0.296875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.870605 3.890625q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm4.9174194 -5.890625l-2.125 0l0 -1.03125l3.390625 0l0 6.15625l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -5.125zm0.4375 -4.046875q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.21875 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.078125 0.171875 -0.21875 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.203125 0 -0.390625 -0.078125q-0.171875 -0.078125 -0.3125 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.140625 -0.140625 0.3125 -0.21875q0.1875 -0.078125 0.390625 -0.078125zm11.54248 1.25q-0.96875 -0.203125 -1.6875 -0.203125q-1.671875 0 -1.671875 1.75l0 1.265625l3.140625 0l0 1.03125l-3.140625 0l0 5.109375l-1.265625 0l0 -5.109375l-2.3125 0l0 -1.03125l2.3125 0l0 -1.1875q0 -2.875 2.984375 -2.875q0.75 0 1.640625 0.171875l0 1.078125zm-7.515625 1.765625l0 0zm11.651794 1.03125l-2.125 0l0 -1.03125l3.390625 0l0 6.15625l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -5.125zm0.4375 -4.046875q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.21875 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.078125 0.171875 -0.21875 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.203125 0 -0.390625 -0.078125q-0.171875 -0.078125 -0.3125 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.140625 -0.140625 0.3125 -0.21875q0.1875 -0.078125 0.390625 -0.078125zm10.76123 9.9375q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625z" fill-rule="nonzero"/><path fill="#20124d" d="m664.59235 183.64816q0 0.84375 -0.25 1.546875q-0.234375 0.6875 -0.671875 1.1875q-0.4375 0.5 -1.078125 0.78125q-0.640625 0.265625 -1.453125 0.265625q-0.765625 0 -1.390625 -0.234375q-0.609375 -0.234375 -1.03125 -0.703125q-0.421875 -0.46875 -0.65625 -1.15625q-0.21875 -0.6875 -0.21875 -1.578125q0 -0.84375 0.234375 -1.53125q0.234375 -0.6875 0.671875 -1.1875q0.453125 -0.5 1.09375 -0.765625q0.640625 -0.28125 1.4375 -0.28125q0.78125 0 1.390625 0.25q0.609375 0.234375 1.03125 0.703125q0.4375 0.453125 0.65625 1.140625q0.234375 0.6875 0.234375 1.5625zm-1.28125 0.0625q0 -0.671875 -0.15625 -1.15625q-0.140625 -0.5 -0.421875 -0.828125q-0.265625 -0.34375 -0.65625 -0.5q-0.375 -0.171875 -0.859375 -0.171875q-0.5625 0 -0.96875 0.21875q-0.390625 0.21875 -0.640625 0.578125q-0.25 0.359375 -0.375 0.84375q-0.109375 0.484375 -0.109375 1.015625q0 0.671875 0.140625 1.171875q0.140625 0.5 0.40625 0.828125q0.28125 0.328125 0.671875 0.5q0.390625 0.171875 0.875 0.171875q0.5625 0 0.953125 -0.21875q0.390625 -0.21875 0.640625 -0.578125q0.265625 -0.375 0.375 -0.859375q0.125 -0.484375 0.125 -1.015625zm9.214355 -0.125q0 0.890625 -0.25 1.59375q-0.234375 0.703125 -0.703125 1.203125q-0.453125 0.484375 -1.109375 0.75q-0.640625 0.25 -1.453125 0.25q-0.640625 0 -1.3125 -0.109375q-0.65625 -0.125 -1.3125 -0.390625l0 -9.6875l1.25 0l0 2.78125l-0.0625 1.328125q0.546875 -0.71875 1.15625 -1.015625q0.609375 -0.296875 1.3125 -0.296875q0.609375 0 1.078125 0.265625q0.46875 0.25 0.78125 0.71875q0.3125 0.46875 0.46875 1.140625q0.15625 0.65625 0.15625 1.46875zm-1.265625 0.046875q0 -0.5625 -0.09375 -1.03125q-0.078125 -0.46875 -0.265625 -0.796875q-0.171875 -0.34375 -0.453125 -0.53125q-0.265625 -0.1875 -0.65625 -0.1875q-0.234375 0 -0.484375 0.078125q-0.234375 0.0625 -0.5 0.25q-0.265625 0.171875 -0.5625 0.46875q-0.28125 0.28125 -0.609375 0.703125l0 3.484375q0.359375 0.140625 0.734375 0.234375q0.390625 0.078125 0.734375 0.078125q0.421875 0 0.8125 -0.125q0.390625 -0.140625 0.6875 -0.453125q0.296875 -0.328125 0.46875 -0.859375q0.1875 -0.53125 0.1875 -1.3125zm8.058044 -3.515625l0 7.0625q0 0.75 -0.21875 1.328125q-0.21875 0.59375 -0.625 0.984375q-0.390625 0.40625 -0.984375 0.609375q-0.578125 0.203125 -1.296875 0.203125q-0.53125 0 -1.046875 -0.09375q-0.5 -0.09375 -0.90625 -0.265625l0 -1.1875q0.21875 0.109375 0.46875 0.203125q0.265625 0.09375 0.53125 0.15625q0.265625 0.0625 0.53125 0.09375q0.28125 0.046875 0.53125 0.046875q0.828125 0 1.28125 -0.515625q0.46875 -0.515625 0.46875 -1.515625l0 -6.078125l-3.515625 0l0 -1.03125l4.78125 0zm-0.75 -3.015625q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.203125 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.0625 0.171875 -0.203125 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.21875 0 -0.40625 -0.078125q-0.171875 -0.078125 -0.296875 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.125 -0.140625 0.296875 -0.21875q0.1875 -0.078125 0.40625 -0.078125zm10.01123 6.234375q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.870544 3.890625q-0.5 0.1875 -1.015625 0.265625q-0.5 0.09375 -1.046875 0.09375q-1.703125 0 -2.625 -0.921875q-0.921875 -0.921875 -0.921875 -2.6875q0 -0.859375 0.265625 -1.546875q0.265625 -0.703125 0.75 -1.1875q0.484375 -0.5 1.140625 -0.765625q0.671875 -0.265625 1.46875 -0.265625q0.5625 0 1.046875 0.078125q0.484375 0.078125 0.9375 0.25l0 1.1875q-0.46875 -0.234375 -0.953125 -0.34375q-0.484375 -0.109375 -1.0 -0.109375q-0.484375 0 -0.90625 0.1875q-0.421875 0.171875 -0.75 0.515625q-0.3125 0.34375 -0.5 0.84375q-0.1875 0.484375 -0.1875 1.109375q0 1.296875 0.625 1.953125q0.640625 0.640625 1.765625 0.640625q0.5 0 0.96875 -0.109375q0.484375 -0.109375 0.9375 -0.34375l0 1.15625zm8.26123 0.171875q-0.421875 0.09375 -0.875 0.140625q-0.453125 0.046875 -0.921875 0.046875q-1.34375 0 -2.015625 -0.609375q-0.65625 -0.609375 -0.65625 -1.875l0 -3.75l-2.015625 0l0 -1.046875l2.015625 0l0 -1.96875l1.234375 -0.328125l0 2.296875l3.234375 0l0 1.046875l-3.234375 0l0 3.65625q0 0.765625 0.40625 1.15625q0.421875 0.375 1.21875 0.375q0.34375 0 0.75 -0.046875q0.40625 -0.0625 0.859375 -0.171875l0 1.078125zm4.7142944 -6.0625l-2.125 0l0 -1.03125l3.390625 0l0 6.15625l2.125 0l0 1.03125l-5.75 0l0 -1.03125l2.359375 0l0 -5.125zm0.4375 -4.046875q0.203125 0 0.375 0.078125q0.1875 0.078125 0.3125 0.21875q0.140625 0.125 0.21875 0.3125q0.078125 0.171875 0.078125 0.375q0 0.203125 -0.078125 0.390625q-0.078125 0.171875 -0.21875 0.3125q-0.125 0.125 -0.3125 0.203125q-0.171875 0.078125 -0.375 0.078125q-0.203125 0 -0.390625 -0.078125q-0.171875 -0.078125 -0.3125 -0.203125q-0.125 -0.140625 -0.203125 -0.3125q-0.078125 -0.1875 -0.078125 -0.390625q0 -0.203125 0.078125 -0.375q0.078125 -0.1875 0.203125 -0.3125q0.140625 -0.140625 0.3125 -0.21875q0.1875 -0.078125 0.390625 -0.078125zm4.4956055 3.015625l1.421875 0l1.765625 4.75l0.375 1.15625l0.390625 -1.1875l1.75 -4.71875l1.359375 0l-2.8125 7.1875l-1.4375 0l-2.8125 -7.1875zm14.808044 3.21875q0 0.265625 -0.015625 0.453125q0 0.171875 -0.015625 0.328125l-5.046875 0q0 1.09375 0.609375 1.6875q0.625 0.59375 1.78125 0.59375q0.3125 0 0.625 -0.015625q0.3125 -0.03125 0.609375 -0.078125q0.296875 -0.046875 0.5625 -0.09375q0.265625 -0.0625 0.5 -0.125l0 1.03125q-0.515625 0.140625 -1.15625 0.21875q-0.640625 0.09375 -1.328125 0.09375q-0.921875 0 -1.59375 -0.25q-0.65625 -0.25 -1.078125 -0.71875q-0.421875 -0.484375 -0.625 -1.171875q-0.203125 -0.6875 -0.203125 -1.5625q0 -0.765625 0.21875 -1.4375q0.21875 -0.671875 0.625 -1.1875q0.421875 -0.515625 1.03125 -0.8125q0.609375 -0.296875 1.375 -0.296875q0.765625 0 1.34375 0.234375q0.578125 0.234375 0.96875 0.671875q0.40625 0.4375 0.609375 1.0625q0.203125 0.609375 0.203125 1.375zm-1.296875 -0.1875q0.015625 -0.46875 -0.109375 -0.859375q-0.109375 -0.40625 -0.34375 -0.6875q-0.234375 -0.296875 -0.59375 -0.453125q-0.359375 -0.15625 -0.828125 -0.15625q-0.40625 0 -0.75 0.15625q-0.328125 0.15625 -0.578125 0.4375q-0.25 0.28125 -0.40625 0.6875q-0.140625 0.40625 -0.171875 0.875l3.78125 0zm8.964355 2.203125q0 0.375 -0.125 0.671875q-0.125 0.296875 -0.34375 0.53125q-0.21875 0.234375 -0.515625 0.40625q-0.296875 0.15625 -0.640625 0.265625q-0.328125 0.109375 -0.6875 0.15625q-0.34375 0.046875 -0.671875 0.046875q-0.734375 0 -1.34375 -0.0625q-0.609375 -0.0625 -1.203125 -0.203125l0 -1.140625q0.640625 0.171875 1.25 0.265625q0.625 0.09375 1.25 0.09375q0.890625 0 1.3125 -0.234375q0.4375 -0.25 0.4375 -0.703125q0 -0.1875 -0.078125 -0.34375q-0.0625 -0.15625 -0.25 -0.296875q-0.171875 -0.140625 -0.546875 -0.28125q-0.375 -0.15625 -1.015625 -0.359375q-0.5 -0.140625 -0.90625 -0.3125q-0.40625 -0.1875 -0.71875 -0.4375q-0.296875 -0.25 -0.46875 -0.578125q-0.171875 -0.34375 -0.171875 -0.8125q0 -0.296875 0.140625 -0.65625q0.140625 -0.359375 0.46875 -0.65625q0.34375 -0.3125 0.921875 -0.515625q0.578125 -0.203125 1.421875 -0.203125q0.421875 0 0.9375 0.046875q0.515625 0.046875 1.078125 0.15625l0 1.109375q-0.578125 -0.140625 -1.109375 -0.203125q-0.53125 -0.078125 -0.90625 -0.078125q-0.46875 0 -0.796875 0.078125q-0.3125 0.0625 -0.515625 0.203125q-0.1875 0.125 -0.28125 0.296875q-0.078125 0.15625 -0.078125 0.34375q0 0.203125 0.0625 0.359375q0.078125 0.15625 0.28125 0.3125q0.21875 0.140625 0.578125 0.28125q0.359375 0.140625 0.953125 0.3125q0.640625 0.1875 1.0625 0.390625q0.4375 0.203125 0.703125 0.46875q0.28125 0.25 0.390625 0.5625q0.125 0.3125 0.125 0.71875z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m748.76117 127.71654l0 -60.787407" fill-rule="evenodd"/><path stroke="#b7b7b7" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m748.76117 127.71654l0 -48.787407" fill-rule="evenodd"/><path fill="#b7b7b7" stroke="#b7b7b7" stroke-width="2.0" stroke-linecap="butt" d="m752.06464 78.92913l-3.3034668 -9.076195l-3.3034668 9.076195z" fill-rule="evenodd"/></g></svg>
\ No newline at end of file
diff --git a/site-src/images/resource-model.png b/site-src/images/resource-model.png
index 0910c5b..216c856 100644
Binary files a/site-src/images/resource-model.png and b/site-src/images/resource-model.png differ
diff --git a/site-src/images/serve-LoRA-adapters.png b/site-src/images/serve-LoRA-adapters.png
deleted file mode 100644
index e33dc70..0000000
Binary files a/site-src/images/serve-LoRA-adapters.png and /dev/null differ
diff --git a/site-src/images/serve-mul-gen-AI-models.png b/site-src/images/serve-mul-gen-AI-models.png
deleted file mode 100644
index 957a054..0000000
Binary files a/site-src/images/serve-mul-gen-AI-models.png and /dev/null differ
diff --git a/site-src/implementations/gateways.md b/site-src/implementations/gateways.md
index 5ab1e09..62abe01 100644
--- a/site-src/implementations/gateways.md
+++ b/site-src/implementations/gateways.md
@@ -8,6 +8,7 @@ This project has several implementations that are planned or in progress:
 * [Google Kubernetes Engine][4]
 * [Istio][5]
 * [Kgateway][6]
+* [Kubvernor][7]
 
 [1]:#agentgateway
 [2]:#alibaba-cloud-container-service-for-kubernetes
@@ -15,12 +16,17 @@ This project has several implementations that are planned or in progress:
 [4]:#google-kubernetes-engine
 [5]:#istio
 [6]:#kgateway
+[7]:#kubvernor
 
 ## Agentgateway
 
-[Agentgateway](https://agentgateway.dev/) is an open source Gateway API implementation focusing on AI use cases, including LLM consumption, LLM serving, agent-to-agent ([A2A](https://a2aproject.github.io/A2A/latest/)), and agent-to-tool ([MCP](https://modelcontextprotocol.io/introduction)). It is the first and only proxy designed specifically for the Kubernetes Gateway API, powered by a high performance and scalable Rust dataplane implementation.
+[Agentgateway](https://agentgateway.dev/) is an open source Gateway API and Inference Gateway
+[v1.0.0 conformant](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/conformance/reports/v1.0.0/gateway/kgateway/agentgateway)
+implementation focusing on AI use cases, including LLM consumption, LLM serving, agent-to-agent ([A2A](https://a2aproject.github.io/A2A/latest/)),
+and agent-to-tool ([MCP](https://modelcontextprotocol.io/introduction)). It is the first and only proxy designed specifically for the Kubernetes Gateway API
+that is powered by a high performance and scalable Rust dataplane.
 
-Agentgateway comes with native support for Gateway API Inference Extension, powered by the [Kgateway](https://kgateway.dev/) control plane.
+Agentgateway can run independently or can be managed by [Kgateway](https://kgateway.dev/).
 
 ## Alibaba Cloud Container Service for Kubernetes
 
@@ -41,7 +47,6 @@ by [this Issue](https://github.com/AliyunContainerService/ack-gateway-api/issues
 [ack-gie]:https://www.alibabacloud.com/help/en/ack/product-overview/ack-gateway-with-inference-extension
 [ack-gie-usage]:https://www.alibabacloud.com/help/en/ack/ack-managed-and-ack-dedicated/user-guide/intelligent-routing-and-traffic-management-with-ack-gateway-inference-extension
 
-
 ## Envoy AI Gateway
 
 [Envoy AI Gateway][aigw-home] is an open source project built on top of 
@@ -88,8 +93,16 @@ Issue](https://github.com/istio/istio/issues/55768).
 
 ## Kgateway
 
-[Kgateway](https://kgateway.dev/) is a Gateway API Inference Extension
-[conformant](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/conformance/reports/v0.5.1/gateway/kgateway)
-gateway that can run [independently](https://gateway-api-inference-extension.sigs.k8s.io/guides/#__tabbed_3_3), as an [Istio waypoint](https://kgateway.dev/blog/extend-istio-ambient-kgateway-waypoint/),
-or within your [llm-d infrastructure](https://github.com/llm-d-incubation/llm-d-infra) to improve accelerator (GPU)
-utilization for AI inference workloads.
+[Kgateway](https://kgateway.dev/) is a Gateway API and Inference Gateway
+[v1.0.0 conformant](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/conformance/reports/v1.0.0/gateway/kgateway)
+implementation that can run [independently](https://gateway-api-inference-extension.sigs.k8s.io/guides/#__tabbed_3_3), as an
+[Istio waypoint](https://kgateway.dev/blog/extend-istio-ambient-kgateway-waypoint/), or within your
+[llm-d infrastructure](https://github.com/llm-d-incubation/llm-d-infra) to improve accelerator (GPU) utilization for AI inference workloads.
+
+## Kubvernor
+
+[Kubvernor Rust API Gateway][krg] is an open-source, highly experimental implementation of API controller in Rust programming language. Currently, Kubvernor supports Envoy Proxy. The project aims to be as generic as possible so Kubvernor can be used to manage/deploy different gateways (Envoy, Nginx, HAProxy, etc.). See the docs for the [usage][krgu].
+
+[krg]:https://github.com/kubvernor/kubvernor
+[krgu]: https://github.com/kubvernor/kubvernor/blob/main/README.md
+
diff --git a/site-src/implementations/model-servers.md b/site-src/implementations/model-servers.md
index da9968f..ed57e12 100644
--- a/site-src/implementations/model-servers.md
+++ b/site-src/implementations/model-servers.md
@@ -19,34 +19,29 @@ vLLM is configured as the default in the [endpoint picker extension](https://git
 
 Triton specific metric names need to be specified when starting the EPP.
 
-### Option 1: Use Helm
+Use `--set inferencePool.modelServerType=triton-tensorrt-llm` to install the `inferencepool` via helm. See the [`inferencepool` helm guide](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/config/charts/inferencepool/README.md) for more details.
 
-Use `--set inferencePool.modelServerType=triton-tensorrt-llm` to install the [`inferencepool` via helm](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/42eb5ff1c5af1275df43ac384df0ddf20da95134/config/charts/inferencepool). See the [`inferencepool` helm guide](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/42eb5ff1c5af1275df43ac384df0ddf20da95134/config/charts/inferencepool/README.md) for more details.
+ Add the following to the `flags` in the helm chart as [flags to EPP](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/29ea29028496a638b162ff287c62c0087211bbe5/config/charts/inferencepool/values.yaml#L36)
 
-### Option 2: Edit EPP deployment yaml
-
- Add the following to the `args` of the [EPP deployment](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/42eb5ff1c5af1275df43ac384df0ddf20da95134/config/manifests/inferencepool-resources.yaml#L32)
-
- ```
-- --total-queued-requests-metric
-- "nv_trt_llm_request_metrics{request_type=waiting}"
-- --kv-cache-usage-percentage-metric
-- "nv_trt_llm_kv_cache_block_metrics{kv_cache_block_type=fraction}"
-- --lora-info-metric
-- "" # Set an empty metric to disable LoRA metric scraping as they are not supported by Triton yet.
+```
+- name=total-queued-requests-metric
+  value="nv_trt_llm_request_metrics{request_type=waiting}"
+- name=kv-cache-usage-percentage-metric
+  value="nv_trt_llm_kv_cache_block_metrics{kv_cache_block_type=fraction}"
+- name=lora-info-metric
+  value="" # Set an empty metric to disable LoRA metric scraping as they are not supported by Triton yet.
 ```
 
 ## SGLang
 
-### Edit EPP deployment yaml
+ Add the following `flags` while deploying using helm charts in the [EPP deployment](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/29ea29028496a638b162ff287c62c0087211bbe5/config/charts/inferencepool/values.yaml#L36)
 
- Add the following to the `args` of the [EPP deployment](https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/42eb5ff1c5af1275df43ac384df0ddf20da95134/config/manifests/inferencepool-resources.yaml#L32)
 
 ```
-- --totalQueuedRequestsMetric
-- "sglang:num_queue_reqs"
-- --kvCacheUsagePercentageMetric
-- "sglang:token_usage"
-- --lora-info-metric
-- "" # Set an empty metric to disable LoRA metric scraping as they are not supported by SGLang yet.
-```
+- name=total-queued-requests-metric
+  value="sglang:num_queue_reqs"
+- name=kv-cache-usage-percentage-metric
+  value="sglang:token_usage"
+- name=lora-info-metric
+  value="" # Set an empty metric to disable LoRA metric scraping as they are not supported by SGLang yet.
+```
\ No newline at end of file
diff --git a/site-src/index.md b/site-src/index.md
index 7a2a116..0fbb338 100644
--- a/site-src/index.md
+++ b/site-src/index.md
@@ -23,8 +23,9 @@ The following specific terms to this project:
   from [Model Serving](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals/003-model-server-protocol/README.md).
 - **Metrics and Capabilities**: Data provided by model serving platforms about
   performance, availability and capabilities to optimize routing. Includes
-  things like [Prefix Cache] status or [LoRA Adapters] availability.
+  things like [Prefix Cache](https://docs.vllm.ai/en/stable/design/v1/prefix_caching.html) status or [LoRA Adapters](https://docs.vllm.ai/en/stable/features/lora.html) availability.
 - **Endpoint Picker(EPP)**: An implementation of an `Inference Scheduler` with additional Routing, Flow, and Request Control layers to allow for sophisticated routing strategies. Additional info on the architecture of the EPP [here](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals/0683-epp-architecture-proposal).
+- **Body Based Router(BBR)**: An additional (and optional) implementation of an extension that extracts information from the body portion of the inference request, currently the model name attribute from the body of an OpenAI API request, which can then be used by the gateway to perform model-aware functions such as routing/scheduling. This may be used along with the EPP in order to have a combination of model picking and endpoint picking functionality.
 
 [Inference Gateway]:#concepts-and-definitions
 
@@ -43,7 +44,7 @@ in a higher level **AI Gateways** like [LiteLLM](https://www.litellm.ai/), [Gloo
 
 - **Model-aware routing**: Instead of simply routing based on the path of the request, an **[inference gateway]** allows you to route to models based on the model names. This is enabled by support for GenAI Inference API specifications (such as OpenAI API) in the gateway implementations such as in Envoy Proxy. This model-aware routing also extends to Low-Rank Adaptation (LoRA) fine-tuned models.
 
-- **Serving priority**: an **[inference gateway]** allows you to specify the serving priority of your models. For example, you can specify that your models for online inference of chat tasks (which is more latency sensitive) have a higher [*Criticality*](/reference/spec/#criticality) than a model for latency tolerant tasks such as a summarization. 
+- **Serving priority**: an **[inference gateway]** allows you to specify the serving priority of your models. For example, you can specify that your models for online inference of chat tasks (which is more latency sensitive) have a higher [*Priority*](/reference/spec/#priority) than a model for latency tolerant tasks such as a summarization. 
 
 - **Model rollouts**:  an **[inference gateway]** allows you to incrementally roll out new model versions by traffic splitting definitions based on the model names. 
 
diff --git a/site-src/reference/spec.md b/site-src/reference/spec.md
index 4260597..666ebe3 100644
--- a/site-src/reference/spec.md
+++ b/site-src/reference/spec.md
@@ -15,101 +15,70 @@ inference.networking.k8s.io API group.
 
 
 
-#### EndpointPickerConfig
-
-
-
-EndpointPickerConfig specifies the configuration needed by the proxy to discover and connect to the endpoint picker extension.
-This type is intended to be a union of mutually exclusive configuration options that we may add in the future.
-
-
-
-_Appears in:_
-- [InferencePoolSpec](#inferencepoolspec)
-
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `extensionRef` _[Extension](#extension)_ | Extension configures an endpoint picker as an extension service. |  | Required: \{\} <br /> |
+#### ControllerName
 
+_Underlying type:_ _string_
 
-#### Extension
+ControllerName is the name of a controller that manages ParentStatus. It must be a domain prefixed
+path.
 
+Valid values include:
 
+* "example.com/bar"
 
-Extension specifies how to configure an extension that runs the endpoint picker.
+Invalid values include:
 
+* "example.com" - must include path
+* "foo.example.com" - must include path
 
+_Validation:_
+- MaxLength: 253
+- MinLength: 1
+- Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$`
 
 _Appears in:_
-- [EndpointPickerConfig](#endpointpickerconfig)
-- [InferencePoolSpec](#inferencepoolspec)
-
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `group` _[Group](#group)_ | Group is the group of the referent.<br />The default value is "", representing the Core API group. |  | MaxLength: 253 <br />Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` <br /> |
-| `kind` _[Kind](#kind)_ | Kind is the Kubernetes resource kind of the referent.<br />Defaults to "Service" when not specified.<br />ExternalName services can refer to CNAME DNS records that may live<br />outside of the cluster and as such are difficult to reason about in<br />terms of conformance. They also may not be safe to forward to (see<br />CVE-2021-25740 for more information). Implementations MUST NOT<br />support ExternalName Services. | Service | MaxLength: 63 <br />MinLength: 1 <br />Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$` <br /> |
-| `name` _[ObjectName](#objectname)_ | Name is the name of the referent. |  | MaxLength: 253 <br />MinLength: 1 <br />Required: \{\} <br /> |
-| `portNumber` _[PortNumber](#portnumber)_ | The port number on the service running the extension. When unspecified,<br />implementations SHOULD infer a default value of 9002 when the Kind is<br />Service. |  | Maximum: 65535 <br />Minimum: 1 <br /> |
-| `failureMode` _[ExtensionFailureMode](#extensionfailuremode)_ | Configures how the gateway handles the case when the extension is not responsive.<br />Defaults to failClose. | FailClose | Enum: [FailOpen FailClose] <br /> |
-
-
-#### ExtensionConnection
-
+- [ParentStatus](#parentstatus)
 
 
-ExtensionConnection encapsulates options that configures the connection to the extension.
-
-
-
-_Appears in:_
-- [Extension](#extension)
-
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `failureMode` _[ExtensionFailureMode](#extensionfailuremode)_ | Configures how the gateway handles the case when the extension is not responsive.<br />Defaults to failClose. | FailClose | Enum: [FailOpen FailClose] <br /> |
 
-
-#### ExtensionFailureMode
+#### EndpointPickerFailureMode
 
 _Underlying type:_ _string_
 
-ExtensionFailureMode defines the options for how the gateway handles the case when the extension is not
-responsive.
+EndpointPickerFailureMode defines the options for how the parent handles the case when the
+Endpoint Picker extension is non-responsive.
 
 _Validation:_
 - Enum: [FailOpen FailClose]
 
 _Appears in:_
-- [Extension](#extension)
-- [ExtensionConnection](#extensionconnection)
+- [EndpointPickerRef](#endpointpickerref)
 
 | Field | Description |
 | --- | --- |
-| `FailOpen` | FailOpen specifies that the proxy should forward the request to an endpoint of its picking when the Endpoint Picker fails.<br /> |
-| `FailClose` | FailClose specifies that the proxy should drop the request when the Endpoint Picker fails.<br /> |
-
+| `FailOpen` | EndpointPickerFailOpen specifies that the parent should forward the request to an endpoint<br />of its picking when the Endpoint Picker extension fails.<br /> |
+| `FailClose` | EndpointPickerFailClose specifies that the parent should drop the request when the Endpoint<br />Picker extension fails.<br /> |
 
-#### ExtensionReference
 
+#### EndpointPickerRef
 
 
-ExtensionReference is a reference to the extension.
 
-If a reference is invalid, the implementation MUST update the `ResolvedRefs`
-Condition on the InferencePool's status to `status: False`. A 5XX status code MUST be returned
-for the request that would have otherwise been routed to the invalid backend.
+EndpointPickerRef specifies a reference to an Endpoint Picker extension and its
+associated configuration.
 
 
 
 _Appears in:_
-- [Extension](#extension)
+- [InferencePoolSpec](#inferencepoolspec)
 
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
-| `group` _[Group](#group)_ | Group is the group of the referent.<br />The default value is "", representing the Core API group. |  | MaxLength: 253 <br />Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` <br /> |
-| `kind` _[Kind](#kind)_ | Kind is the Kubernetes resource kind of the referent.<br />Defaults to "Service" when not specified.<br />ExternalName services can refer to CNAME DNS records that may live<br />outside of the cluster and as such are difficult to reason about in<br />terms of conformance. They also may not be safe to forward to (see<br />CVE-2021-25740 for more information). Implementations MUST NOT<br />support ExternalName Services. | Service | MaxLength: 63 <br />MinLength: 1 <br />Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$` <br /> |
-| `name` _[ObjectName](#objectname)_ | Name is the name of the referent. |  | MaxLength: 253 <br />MinLength: 1 <br />Required: \{\} <br /> |
-| `portNumber` _[PortNumber](#portnumber)_ | The port number on the service running the extension. When unspecified,<br />implementations SHOULD infer a default value of 9002 when the Kind is<br />Service. |  | Maximum: 65535 <br />Minimum: 1 <br /> |
+| `group` _[Group](#group)_ | Group is the group of the referent API object. When unspecified, the default value<br />is "", representing the Core API group. |  | MaxLength: 253 <br />MinLength: 0 <br />Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` <br /> |
+| `kind` _[Kind](#kind)_ | Kind is the Kubernetes resource kind of the referent.<br />Required if the referent is ambiguous, e.g. service with multiple ports.<br />Defaults to "Service" when not specified.<br />ExternalName services can refer to CNAME DNS records that may live<br />outside of the cluster and as such are difficult to reason about in<br />terms of conformance. They also may not be safe to forward to (see<br />CVE-2021-25740 for more information). Implementations MUST NOT<br />support ExternalName Services. | Service | MaxLength: 63 <br />MinLength: 1 <br />Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$` <br /> |
+| `name` _[ObjectName](#objectname)_ | Name is the name of the referent API object. |  | MaxLength: 253 <br />MinLength: 1 <br /> |
+| `port` _[Port](#port)_ | Port is the port of the Endpoint Picker extension service.<br />Port is required when the referent is a Kubernetes Service. In this<br />case, the port number is the service port number, not the target port.<br />For other resources, destination port might be derived from the referent<br />resource or this field. |  |  |
+| `failureMode` _[EndpointPickerFailureMode](#endpointpickerfailuremode)_ | FailureMode configures how the parent handles the case when the Endpoint Picker extension<br />is non-responsive. When unspecified, defaults to "FailClose". | FailClose | Enum: [FailOpen FailClose] <br /> |
 
 
 #### Group
@@ -134,12 +103,12 @@ Invalid values include:
 
 _Validation:_
 - MaxLength: 253
+- MinLength: 0
 - Pattern: `^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
 
 _Appears in:_
-- [Extension](#extension)
-- [ExtensionReference](#extensionreference)
-- [ParentGatewayReference](#parentgatewayreference)
+- [EndpointPickerRef](#endpointpickerref)
+- [ParentReference](#parentreference)
 
 
 
@@ -159,8 +128,8 @@ InferencePool is the Schema for the InferencePools API.
 | `apiVersion` _string_ | `inference.networking.k8s.io/v1` | | |
 | `kind` _string_ | `InferencePool` | | |
 | `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |  |  |
-| `spec` _[InferencePoolSpec](#inferencepoolspec)_ |  |  |  |
-| `status` _[InferencePoolStatus](#inferencepoolstatus)_ | Status defines the observed state of InferencePool. | \{ parent:[map[conditions:[map[lastTransitionTime:1970-01-01T00:00:00Z message:Waiting for controller reason:Pending status:Unknown type:Accepted]] parentRef:map[kind:Status name:default]]] \} |  |
+| `spec` _[InferencePoolSpec](#inferencepoolspec)_ | Spec defines the desired state of the InferencePool. |  |  |
+| `status` _[InferencePoolStatus](#inferencepoolstatus)_ | Status defines the observed state of the InferencePool. |  |  |
 
 
 
@@ -171,7 +140,7 @@ InferencePool is the Schema for the InferencePools API.
 
 
 
-InferencePoolSpec defines the desired state of InferencePool
+InferencePoolSpec defines the desired state of the InferencePool.
 
 
 
@@ -180,16 +149,16 @@ _Appears in:_
 
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
-| `selector` _object (keys:[LabelKey](#labelkey), values:[LabelValue](#labelvalue))_ | Selector defines a map of labels to watch model server Pods<br />that should be included in the InferencePool.<br />In some cases, implementations may translate this field to a Service selector, so this matches the simple<br />map used for Service selectors instead of the full Kubernetes LabelSelector type.<br />If specified, it will be applied to match the model server pods in the same namespace as the InferencePool.<br />Cross namesoace selector is not supported. |  | Required: \{\} <br /> |
-| `targetPortNumber` _integer_ | TargetPortNumber defines the port number to access the selected model server Pods.<br />The number must be in the range 1 to 65535. |  | Maximum: 65535 <br />Minimum: 1 <br />Required: \{\} <br /> |
-| `extensionRef` _[Extension](#extension)_ | Extension configures an endpoint picker as an extension service. |  | Required: \{\} <br /> |
+| `selector` _[LabelSelector](#labelselector)_ | Selector determines which Pods are members of this inference pool.<br />It matches Pods by their labels only within the same namespace; cross-namespace<br />selection is not supported.<br />The structure of this LabelSelector is intentionally simple to be compatible<br />with Kubernetes Service selectors, as some implementations may translate<br />this configuration into a Service resource. |  |  |
+| `targetPorts` _[Port](#port) array_ | TargetPorts defines a list of ports that are exposed by this InferencePool.<br />Every port will be treated as a distinctive endpoint by EPP,<br />addressable as a 'podIP:portNumber' combination. |  | MaxItems: 8 <br />MinItems: 1 <br /> |
+| `endpointPickerRef` _[EndpointPickerRef](#endpointpickerref)_ | EndpointPickerRef is a reference to the Endpoint Picker extension and its<br />associated configuration. |  |  |
 
 
 #### InferencePoolStatus
 
 
 
-InferencePoolStatus defines the observed state of InferencePool.
+InferencePoolStatus defines the observed state of the InferencePool.
 
 
 
@@ -198,7 +167,7 @@ _Appears in:_
 
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
-| `parent` _[PoolStatus](#poolstatus) array_ | Parents is a list of parent resources (usually Gateways) that are<br />associated with the InferencePool, and the status of the InferencePool with respect to<br />each parent.<br />A maximum of 32 Gateways will be represented in this list. When the list contains<br />`kind: Status, name: default`, it indicates that the InferencePool is not<br />associated with any Gateway and a controller must perform the following:<br /> - Remove the parent when setting the "Accepted" condition.<br /> - Add the parent when the controller will no longer manage the InferencePool<br />   and no other parents exist. |  | MaxItems: 32 <br /> |
+| `parents` _[ParentStatus](#parentstatus) array_ | Parents is a list of parent resources, typically Gateways, that are associated with<br />the InferencePool, and the status of the InferencePool with respect to each parent.<br />A controller that manages the InferencePool, must add an entry for each parent it manages<br />and remove the parent entry when the controller no longer considers the InferencePool to<br />be associated with that parent.<br />A maximum of 32 parents will be represented in this list. When the list is empty,<br />it indicates that the InferencePool is not associated with any parents. |  | MaxItems: 32 <br /> |
 
 
 #### Kind
@@ -222,9 +191,8 @@ _Validation:_
 - Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$`
 
 _Appears in:_
-- [Extension](#extension)
-- [ExtensionReference](#extensionreference)
-- [ParentGatewayReference](#parentgatewayreference)
+- [EndpointPickerRef](#endpointpickerref)
+- [ParentReference](#parentreference)
 
 
 
@@ -256,9 +224,26 @@ _Validation:_
 - MinLength: 1
 - 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_.]{0,61})?[A-Za-z0-9]$`
 
+_Appears in:_
+- [LabelSelector](#labelselector)
+
+
+
+#### LabelSelector
+
+
+
+LabelSelector defines a query for resources based on their labels.
+This simplified version uses only the matchLabels field.
+
+
+
 _Appears in:_
 - [InferencePoolSpec](#inferencepoolspec)
 
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `matchLabels` _object (keys:[LabelKey](#labelkey), values:[LabelValue](#labelvalue))_ | MatchLabels contains a set of required \{key,value\} pairs.<br />An object must match every label in this map to be selected.<br />The matching logic is an AND operation on all entries. |  | MaxItems: 64 <br />MinItems: 1 <br /> |
 
 
 #### LabelValue
@@ -283,7 +268,7 @@ _Validation:_
 - Pattern: `^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$`
 
 _Appears in:_
-- [InferencePoolSpec](#inferencepoolspec)
+- [LabelSelector](#labelselector)
 
 
 
@@ -313,7 +298,7 @@ _Validation:_
 - Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
 
 _Appears in:_
-- [ParentGatewayReference](#parentgatewayreference)
+- [ParentReference](#parentreference)
 
 
 
@@ -330,37 +315,36 @@ _Validation:_
 - MinLength: 1
 
 _Appears in:_
-- [Extension](#extension)
-- [ExtensionReference](#extensionreference)
-- [ParentGatewayReference](#parentgatewayreference)
+- [EndpointPickerRef](#endpointpickerref)
+- [ParentReference](#parentreference)
 
 
 
-#### ParentGatewayReference
+#### ParentReference
 
 
 
-ParentGatewayReference identifies an API object including its namespace,
-defaulting to Gateway.
+ParentReference identifies an API object. It is used to associate the InferencePool with a
+parent resource, such as a Gateway.
 
 
 
 _Appears in:_
-- [PoolStatus](#poolstatus)
+- [ParentStatus](#parentstatus)
 
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
-| `group` _[Group](#group)_ | Group is the group of the referent. | gateway.networking.k8s.io | MaxLength: 253 <br />Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` <br /> |
-| `kind` _[Kind](#kind)_ | Kind is kind of the referent. For example "Gateway". | Gateway | MaxLength: 63 <br />MinLength: 1 <br />Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$` <br /> |
-| `name` _[ObjectName](#objectname)_ | Name is the name of the referent. |  | MaxLength: 253 <br />MinLength: 1 <br /> |
-| `namespace` _[Namespace](#namespace)_ | Namespace is the namespace of the referent.  If not present,<br />the namespace of the referent is assumed to be the same as<br />the namespace of the referring object. |  | MaxLength: 63 <br />MinLength: 1 <br />Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$` <br /> |
+| `group` _[Group](#group)_ | Group is the group of the referent API object. When unspecified, the referent is assumed<br />to be in the "gateway.networking.k8s.io" API group. | gateway.networking.k8s.io | MaxLength: 253 <br />MinLength: 0 <br />Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` <br /> |
+| `kind` _[Kind](#kind)_ | Kind is the kind of the referent API object. When unspecified, the referent is assumed<br />to be a "Gateway" kind. | Gateway | MaxLength: 63 <br />MinLength: 1 <br />Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$` <br /> |
+| `name` _[ObjectName](#objectname)_ | Name is the name of the referent API object. |  | MaxLength: 253 <br />MinLength: 1 <br /> |
+| `namespace` _[Namespace](#namespace)_ | Namespace is the namespace of the referenced object. When unspecified, the local<br />namespace is inferred.<br />Note that when a namespace different than the local namespace is specified,<br />a ReferenceGrant object is required in the referent namespace to allow that<br />namespace's owner to accept the reference. See the ReferenceGrant<br />documentation for details: https://gateway-api.sigs.k8s.io/api-types/referencegrant/ |  | MaxLength: 63 <br />MinLength: 1 <br />Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$` <br /> |
 
 
-#### PoolStatus
+#### ParentStatus
 
 
 
-PoolStatus defines the observed state of InferencePool from a Gateway.
+ParentStatus defines the observed state of InferencePool from a Parent, i.e. Gateway.
 
 
 
@@ -369,8 +353,26 @@ _Appears in:_
 
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
-| `parentRef` _[ParentGatewayReference](#parentgatewayreference)_ | GatewayRef indicates the gateway that observed state of InferencePool. |  |  |
-| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions track the state of the InferencePool.<br />Known condition types are:<br />* "Accepted"<br />* "ResolvedRefs" | [map[lastTransitionTime:1970-01-01T00:00:00Z message:Waiting for controller reason:Pending status:Unknown type:Accepted]] | MaxItems: 8 <br /> |
+| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions is a list of status conditions that provide information about the observed<br />state of the InferencePool. This field is required to be set by the controller that<br />manages the InferencePool.<br />Supported condition types are:<br />* "Accepted"<br />* "ResolvedRefs" |  | MaxItems: 8 <br /> |
+| `parentRef` _[ParentReference](#parentreference)_ | ParentRef is used to identify the parent resource that this status<br />is associated with. It is used to match the InferencePool with the parent<br />resource, such as a Gateway. |  |  |
+| `controllerName` _[ControllerName](#controllername)_ | ControllerName is a domain/path string that indicates the name of the controller that<br />wrote this status. This corresponds with the GatewayClass controllerName field when the<br />parentRef references a Gateway kind.<br />Example: "example.net/gateway-controller".<br />The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are valid Kubernetes names:<br /> https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names<br />Controllers MAY populate this field when writing status. When populating this field, controllers<br />should ensure that entries to status populated with their ControllerName are cleaned up when they<br />are no longer necessary. |  | MaxLength: 253 <br />MinLength: 1 <br />Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$` <br /> |
+
+
+#### Port
+
+
+
+Port defines the network port that will be exposed by this InferencePool.
+
+
+
+_Appears in:_
+- [EndpointPickerRef](#endpointpickerref)
+- [InferencePoolSpec](#inferencepoolspec)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `number` _[PortNumber](#portnumber)_ | Number defines the port number to access the selected model server Pods.<br />The number must be in the range 1 to 65535. |  | Maximum: 65535 <br />Minimum: 1 <br /> |
 
 
 #### PortNumber
@@ -384,8 +386,7 @@ _Validation:_
 - Minimum: 1
 
 _Appears in:_
-- [Extension](#extension)
-- [ExtensionReference](#extensionreference)
+- [Port](#port)
 
 
 
diff --git a/site-src/reference/x-v1a1-spec.md b/site-src/reference/x-v1a1-spec.md
new file mode 100644
index 0000000..55bec76
--- /dev/null
+++ b/site-src/reference/x-v1a1-spec.md
@@ -0,0 +1,126 @@
+# API Reference
+
+## Packages
+- [inference.networking.x-k8s.io/v1alpha1](#inferencenetworkingx-k8siov1alpha1)
+
+
+## inference.networking.x-k8s.io/v1alpha1
+
+Package v1alpha1 contains API Schema definitions for the
+inference.networking.x-k8s.io API group.
+
+
+### Resource Types
+- [InferencePoolImport](#inferencepoolimport)
+
+
+
+#### ClusterName
+
+_Underlying type:_ _string_
+
+ClusterName is the name of a cluster that exported the InferencePool.
+
+_Validation:_
+- MaxLength: 253
+- MinLength: 1
+
+_Appears in:_
+- [ExportingCluster](#exportingcluster)
+
+
+
+#### ControllerName
+
+_Underlying type:_ _string_
+
+ControllerName is the name of a controller that manages a resource. It must be a domain prefixed path.
+
+Valid values include:
+
+  - "example.com/bar"
+
+Invalid values include:
+
+  - "example.com" - must include path
+  - "foo.example.com" - must include path
+
+_Validation:_
+- MaxLength: 253
+- MinLength: 1
+- Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$`
+
+_Appears in:_
+- [ImportController](#importcontroller)
+
+
+
+#### ExportingCluster
+
+
+
+ExportingCluster defines a cluster that exported the InferencePool that backs this InferencePoolImport.
+
+
+
+_Appears in:_
+- [ImportController](#importcontroller)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `name` _[ClusterName](#clustername)_ | Name of the exporting cluster (must be unique within the list). |  | MaxLength: 253 <br />MinLength: 1 <br />Required: \{\} <br /> |
+
+
+#### ImportController
+
+
+
+ImportController defines a controller that is responsible for managing the InferencePoolImport.
+
+
+
+_Appears in:_
+- [InferencePoolImportStatus](#inferencepoolimportstatus)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `name` _[ControllerName](#controllername)_ | Name is a domain/path string that indicates the name of the controller that manages the<br />InferencePoolImport. Name corresponds to the GatewayClass controllerName field when the<br />controller will manage parents of type "Gateway". Otherwise, the name is implementation-specific.<br />Example: "example.net/import-controller".<br />The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are valid Kubernetes<br />names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).<br />A controller MUST populate this field when writing status and ensure that entries to status<br />populated with their controller name are removed when they are no longer necessary. |  | MaxLength: 253 <br />MinLength: 1 <br />Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$` <br /> |
+| `exportingClusters` _[ExportingCluster](#exportingcluster) array_ | ExportingClusters is a list of clusters that exported the InferencePool(s) that back the<br />InferencePoolImport. Required when the controller is responsible for CRUD'ing the InferencePoolImport<br />from the exported InferencePool(s). |  |  |
+| `parents` _ParentStatus array_ | Parents is a list of parent resources, typically Gateways, that are associated with the<br />InferencePoolImport, and the status of the InferencePoolImport with respect to each parent.<br />Ancestor would be a more accurate name, but Parent is consistent with InferencePool terminology.<br />Required when the controller manages the InferencePoolImport as an HTTPRoute backendRef. The controller<br />must add an entry for each parent it manages and remove the parent entry when the controller no longer<br />considers the InferencePoolImport to be associated with that parent. |  |  |
+| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions track the state of the InferencePoolImport.<br />Known condition types are:<br /> * "Accepted" |  | MaxItems: 8 <br /> |
+
+
+#### InferencePoolImport
+
+
+
+InferencePoolImport is the Schema for the InferencePoolImports API.
+
+
+
+
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `apiVersion` _string_ | `inference.networking.x-k8s.io/v1alpha1` | | |
+| `kind` _string_ | `InferencePoolImport` | | |
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |  |  |
+| `status` _[InferencePoolImportStatus](#inferencepoolimportstatus)_ | Status defines the observed state of the InferencePoolImport. |  |  |
+
+
+#### InferencePoolImportStatus
+
+
+
+InferencePoolImportStatus defines the observed state of the InferencePoolImport.
+
+
+
+_Appears in:_
+- [InferencePoolImport](#inferencepoolimport)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `controllers` _[ImportController](#importcontroller) array_ | Controllers is a list of controllers that are responsible for managing the InferencePoolImport. |  | MaxItems: 8 <br />Required: \{\} <br /> |
+
+
diff --git a/site-src/reference/x-spec.md b/site-src/reference/x-v1a2-spec.md
similarity index 58%
rename from site-src/reference/x-spec.md
rename to site-src/reference/x-v1a2-spec.md
index 5791e8d..c1a57ce 100644
--- a/site-src/reference/x-spec.md
+++ b/site-src/reference/x-v1a2-spec.md
@@ -11,49 +11,11 @@ inference.networking.x-k8s.io API group.
 
 
 ### Resource Types
-- [InferenceModel](#inferencemodel)
+- [InferenceObjective](#inferenceobjective)
 - [InferencePool](#inferencepool)
 
 
 
-#### Criticality
-
-_Underlying type:_ _string_
-
-Criticality defines how important it is to serve the model compared to other models.
-Criticality is intentionally a bounded enum to contain the possibilities that need to be supported by the load balancing algorithm. Any reference to the Criticality field must be optional (use a pointer), and set no default.
-This allows us to union this with a oneOf field in the future should we wish to adjust/extend this behavior.
-
-_Validation:_
-- Enum: [Critical Standard Sheddable]
-
-_Appears in:_
-- [InferenceModelSpec](#inferencemodelspec)
-
-| Field | Description |
-| --- | --- |
-| `Critical` | Critical defines the highest level of criticality. Requests to this band will be shed last.<br /> |
-| `Standard` | Standard defines the base criticality level and is more important than Sheddable but less<br />important than Critical. Requests in this band will be shed before critical traffic.<br />Most models are expected to fall within this band.<br /> |
-| `Sheddable` | Sheddable defines the lowest level of criticality. Requests to this band will be shed before<br />all other bands.<br /> |
-
-
-#### EndpointPickerConfig
-
-
-
-EndpointPickerConfig specifies the configuration needed by the proxy to discover and connect to the endpoint picker extension.
-This type is intended to be a union of mutually exclusive configuration options that we may add in the future.
-
-
-
-_Appears in:_
-- [InferencePoolSpec](#inferencepoolspec)
-
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `extensionRef` _[Extension](#extension)_ | Extension configures an endpoint picker as an extension service. |  | Required: \{\} <br /> |
-
-
 #### Extension
 
 
@@ -63,7 +25,6 @@ Extension specifies how to configure an extension that runs the endpoint picker.
 
 
 _Appears in:_
-- [EndpointPickerConfig](#endpointpickerconfig)
 - [InferencePoolSpec](#inferencepoolspec)
 
 | Field | Description | Default | Validation |
@@ -75,22 +36,6 @@ _Appears in:_
 | `failureMode` _[ExtensionFailureMode](#extensionfailuremode)_ | Configures how the gateway handles the case when the extension is not responsive.<br />Defaults to failClose. | FailClose | Enum: [FailOpen FailClose] <br /> |
 
 
-#### ExtensionConnection
-
-
-
-ExtensionConnection encapsulates options that configures the connection to the extension.
-
-
-
-_Appears in:_
-- [Extension](#extension)
-
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `failureMode` _[ExtensionFailureMode](#extensionfailuremode)_ | Configures how the gateway handles the case when the extension is not responsive.<br />Defaults to failClose. | FailClose | Enum: [FailOpen FailClose] <br /> |
-
-
 #### ExtensionFailureMode
 
 _Underlying type:_ _string_
@@ -103,7 +48,6 @@ _Validation:_
 
 _Appears in:_
 - [Extension](#extension)
-- [ExtensionConnection](#extensionconnection)
 
 | Field | Description |
 | --- | --- |
@@ -111,34 +55,6 @@ _Appears in:_
 | `FailClose` | FailClose specifies that the proxy should drop the request when the Endpoint Picker fails.<br /> |
 
 
-#### ExtensionReference
-
-
-
-ExtensionReference is a reference to the extension.
-
-Connections to this extension MUST use TLS by default. Implementations MAY
-provide a way to customize this connection to use cleartext, a different
-protocol, or custom TLS configuration.
-
-If a reference is invalid, the implementation MUST update the `ResolvedRefs`
-Condition on the InferencePool's status to `status: False`. A 5XX status code
-MUST be returned for the request that would have otherwise been routed to the
-invalid backend.
-
-
-
-_Appears in:_
-- [Extension](#extension)
-
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `group` _[Group](#group)_ | Group is the group of the referent.<br />The default value is "", representing the Core API group. |  | MaxLength: 253 <br />Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` <br /> |
-| `kind` _[Kind](#kind)_ | Kind is the Kubernetes resource kind of the referent.<br />Defaults to "Service" when not specified.<br />ExternalName services can refer to CNAME DNS records that may live<br />outside of the cluster and as such are difficult to reason about in<br />terms of conformance. They also may not be safe to forward to (see<br />CVE-2021-25740 for more information). Implementations MUST NOT<br />support ExternalName Services. | Service | MaxLength: 63 <br />MinLength: 1 <br />Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$` <br /> |
-| `name` _[ObjectName](#objectname)_ | Name is the name of the referent. |  | MaxLength: 253 <br />MinLength: 1 <br />Required: \{\} <br /> |
-| `portNumber` _[PortNumber](#portnumber)_ | The port number on the service running the extension. When unspecified,<br />implementations SHOULD infer a default value of 9002 when the Kind is<br />Service. |  | Maximum: 65535 <br />Minimum: 1 <br /> |
-
-
 #### Group
 
 _Underlying type:_ _string_
@@ -165,17 +81,16 @@ _Validation:_
 
 _Appears in:_
 - [Extension](#extension)
-- [ExtensionReference](#extensionreference)
 - [ParentGatewayReference](#parentgatewayreference)
 - [PoolObjectReference](#poolobjectreference)
 
 
 
-#### InferenceModel
+#### InferenceObjective
 
 
 
-InferenceModel is the Schema for the InferenceModels API.
+InferenceObjective is the Schema for the InferenceObjectives API.
 
 
 
@@ -184,21 +99,21 @@ InferenceModel is the Schema for the InferenceModels API.
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
 | `apiVersion` _string_ | `inference.networking.x-k8s.io/v1alpha2` | | |
-| `kind` _string_ | `InferenceModel` | | |
+| `kind` _string_ | `InferenceObjective` | | |
 | `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |  |  |
-| `spec` _[InferenceModelSpec](#inferencemodelspec)_ |  |  |  |
-| `status` _[InferenceModelStatus](#inferencemodelstatus)_ |  |  |  |
+| `spec` _[InferenceObjectiveSpec](#inferenceobjectivespec)_ |  |  |  |
+| `status` _[InferenceObjectiveStatus](#inferenceobjectivestatus)_ |  |  |  |
 
 
 
 
 
 
-#### InferenceModelSpec
+#### InferenceObjectiveSpec
 
 
 
-InferenceModelSpec represents the desired state of a specific model use case. This resource is
+InferenceObjectiveSpec represents the desired state of a specific model use case. This resource is
 managed by the "Inference Workload Owner" persona.
 
 The Inference Workload Owner persona is someone that trains, verifies, and
@@ -206,41 +121,33 @@ leverages a large language model from a model frontend, drives the lifecycle
 and rollout of new versions of those models, and defines the specific
 performance and latency goals for the model. These workloads are
 expected to operate within an InferencePool sharing compute capacity with other
-InferenceModels, defined by the Inference Platform Admin.
-
-InferenceModel's modelName (not the ObjectMeta name) is unique for a given InferencePool,
-if the name is reused, an error will be shown on the status of a
-InferenceModel that attempted to reuse. The oldest InferenceModel, based on
-creation timestamp, will be selected to remain valid. In the event of a race
-condition, one will be selected at random.
+InferenceObjectives, defined by the Inference Platform Admin.
 
 
 
 _Appears in:_
-- [InferenceModel](#inferencemodel)
+- [InferenceObjective](#inferenceobjective)
 
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
-| `modelName` _string_ | ModelName is the name of the model as it will be set in the "model" parameter for an incoming request.<br />ModelNames must be unique for a referencing InferencePool<br />(names can be reused for a different pool in the same cluster).<br />The modelName with the oldest creation timestamp is retained, and the incoming<br />InferenceModel's Ready status is set to false with a corresponding reason.<br />In the rare case of a race condition, one Model will be selected randomly to be considered valid, and the other rejected.<br />Names can be reserved without an underlying model configured in the pool.<br />This can be done by specifying a target model and setting the weight to zero,<br />an error will be returned specifying that no valid target model is found. |  | MaxLength: 256 <br />Required: \{\} <br /> |
-| `criticality` _[Criticality](#criticality)_ | Criticality defines how important it is to serve the model compared to other models referencing the same pool.<br />Criticality impacts how traffic is handled in resource constrained situations. It handles this by<br />queuing or rejecting requests of lower criticality. InferenceModels of an equivalent Criticality will<br />fairly share resources over throughput of tokens. In the future, the metric used to calculate fairness,<br />and the proportionality of fairness will be configurable.<br />Default values for this field will not be set, to allow for future additions of new field that may 'one of' with this field.<br />Any implementations that may consume this field may treat an unset value as the 'Standard' range. |  | Enum: [Critical Standard Sheddable] <br /> |
-| `targetModels` _[TargetModel](#targetmodel) array_ | TargetModels allow multiple versions of a model for traffic splitting.<br />If not specified, the target model name is defaulted to the modelName parameter.<br />modelName is often in reference to a LoRA adapter. |  | MaxItems: 10 <br /> |
+| `priority` _integer_ | Priority defines how important it is to serve the request compared to other requests in the same pool.<br />Priority is an integer value that defines the priority of the request.<br />The higher the value, the more critical the request is; negative values _are_ allowed.<br />No default value is set for this field, allowing for future additions of new fields that may 'one of' with this field.<br />However, implementations that consume this field (such as the Endpoint Picker) will treat an unset value as '0'.<br />Priority is used in flow control, primarily in the event of resource scarcity(requests need to be queued).<br />All requests will be queued, and flow control will _always_ allow requests of higher priority to be served first.<br />Fairness is only enforced and tracked between requests of the same priority.<br />Example: requests with Priority 10 will always be served before<br />requests with Priority of 0 (the value used if Priority is unset or no InfereneceObjective is specified).<br />Similarly requests with a Priority of -10 will always be served after requests with Priority of 0. |  |  |
 | `poolRef` _[PoolObjectReference](#poolobjectreference)_ | PoolRef is a reference to the inference pool, the pool must exist in the same namespace. |  | Required: \{\} <br /> |
 
 
-#### InferenceModelStatus
+#### InferenceObjectiveStatus
 
 
 
-InferenceModelStatus defines the observed state of InferenceModel
+InferenceObjectiveStatus defines the observed state of InferenceObjective
 
 
 
 _Appears in:_
-- [InferenceModel](#inferencemodel)
+- [InferenceObjective](#inferenceobjective)
 
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
-| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions track the state of the InferenceModel.<br />Known condition types are:<br />* "Accepted" | [map[lastTransitionTime:1970-01-01T00:00:00Z message:Waiting for controller reason:Pending status:Unknown type:Ready]] | MaxItems: 8 <br /> |
+| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions track the state of the InferenceObjective.<br />Known condition types are:<br />* "Accepted" | [map[lastTransitionTime:1970-01-01T00:00:00Z message:Waiting for controller reason:Pending status:Unknown type:Ready]] | MaxItems: 8 <br /> |
 
 
 #### InferencePool
@@ -253,7 +160,6 @@ InferencePool is the Schema for the InferencePools API.
 
 
 
-
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
 | `apiVersion` _string_ | `inference.networking.x-k8s.io/v1alpha2` | | |
@@ -282,7 +188,7 @@ _Appears in:_
 | --- | --- | --- | --- |
 | `selector` _object (keys:[LabelKey](#labelkey), values:[LabelValue](#labelvalue))_ | Selector defines a map of labels to watch model server Pods<br />that should be included in the InferencePool.<br />In some cases, implementations may translate this field to a Service selector, so this matches the simple<br />map used for Service selectors instead of the full Kubernetes LabelSelector type.<br />If specified, it will be applied to match the model server pods in the same namespace as the InferencePool.<br />Cross namesoace selector is not supported. |  | Required: \{\} <br /> |
 | `targetPortNumber` _integer_ | TargetPortNumber defines the port number to access the selected model server Pods.<br />The number must be in the range 1 to 65535. |  | Maximum: 65535 <br />Minimum: 1 <br />Required: \{\} <br /> |
-| `extensionRef` _[Extension](#extension)_ | Extension configures an endpoint picker as an extension service. |  | Required: \{\} <br /> |
+| `extensionRef` _[Extension](#extension)_ | Extension configures an endpoint picker as an extension service. |  |  |
 
 
 #### InferencePoolStatus
@@ -323,7 +229,6 @@ _Validation:_
 
 _Appears in:_
 - [Extension](#extension)
-- [ExtensionReference](#extensionreference)
 - [ParentGatewayReference](#parentgatewayreference)
 - [PoolObjectReference](#poolobjectreference)
 
@@ -432,7 +337,6 @@ _Validation:_
 
 _Appears in:_
 - [Extension](#extension)
-- [ExtensionReference](#extensionreference)
 - [ParentGatewayReference](#parentgatewayreference)
 - [PoolObjectReference](#poolobjectreference)
 
@@ -468,11 +372,11 @@ referrer.
 
 
 _Appears in:_
-- [InferenceModelSpec](#inferencemodelspec)
+- [InferenceObjectiveSpec](#inferenceobjectivespec)
 
 | Field | Description | Default | Validation |
 | --- | --- | --- | --- |
-| `group` _[Group](#group)_ | Group is the group of the referent. | inference.networking.x-k8s.io | MaxLength: 253 <br />Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` <br /> |
+| `group` _[Group](#group)_ | Group is the group of the referent. | inference.networking.k8s.io | MaxLength: 253 <br />Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` <br /> |
 | `kind` _[Kind](#kind)_ | Kind is kind of the referent. For example "InferencePool". | InferencePool | MaxLength: 63 <br />MinLength: 1 <br />Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$` <br /> |
 | `name` _[ObjectName](#objectname)_ | Name is the name of the referent. |  | MaxLength: 253 <br />MinLength: 1 <br />Required: \{\} <br /> |
 
@@ -506,30 +410,6 @@ _Validation:_
 
 _Appears in:_
 - [Extension](#extension)
-- [ExtensionReference](#extensionreference)
-
-
-
-#### TargetModel
 
 
 
-TargetModel represents a deployed model or a LoRA adapter. The
-Name field is expected to match the name of the LoRA adapter
-(or base model) as it is registered within the model server. Inference
-Gateway assumes that the model exists on the model server and it's the
-responsibility of the user to validate a correct match. Should a model fail
-to exist at request time, the error is processed by the Inference Gateway
-and emitted on the appropriate InferenceModel object.
-
-
-
-_Appears in:_
-- [InferenceModelSpec](#inferencemodelspec)
-
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `name` _string_ | Name is the name of the adapter or base model, as expected by the ModelServer. |  | MaxLength: 253 <br />Required: \{\} <br /> |
-| `weight` _integer_ | Weight is used to determine the proportion of traffic that should be<br />sent to this model when multiple target models are specified.<br />Weight defines the proportion of requests forwarded to the specified<br />model. This is computed as weight/(sum of all weights in this<br />TargetModels list). For non-zero values, there may be some epsilon from<br />the exact proportion defined here depending on the precision an<br />implementation supports. Weight is not a percentage and the sum of<br />weights does not need to equal 100.<br />If a weight is set for any targetModel, it must be set for all targetModels.<br />Conversely weights are optional, so long as ALL targetModels do not specify a weight. |  | Maximum: 1e+06 <br />Minimum: 1 <br /> |
-
-
diff --git a/tools/alerts/alert.yaml b/tools/alerts/alert.yaml
index c712207..687123f 100644
--- a/tools/alerts/alert.yaml
+++ b/tools/alerts/alert.yaml
@@ -5,7 +5,7 @@ groups:
     annotations:
       title: 'High latency (P99) for model {{ $labels.model_name }}'
       description: 'The 99th percentile request duration for model {{ $labels.model_name }} and target model {{ $labels.target_model_name }} has been consistently above 10.0 seconds for 5 minutes.'
-    expr: histogram_quantile(0.99, rate(inference_model_request_duration_seconds_bucket[5m])) > 10.0
+    expr: histogram_quantile(0.99, rate(inference_objective_request_duration_seconds_bucket[5m])) > 10.0
     for: 5m
     labels:
       severity: 'warning'
@@ -13,7 +13,7 @@ groups:
     annotations:
       title: 'High error rate for model {{ $labels.model_name }}'
       description: 'The error rate for model {{ $labels.model_name }} and target model {{ $labels.target_model_name }} has been consistently above 5% for 5 minutes.'
-    expr: sum by (model_name) (rate(inference_model_request_error_total[5m])) / sum by (model_name) (rate(inference_model_request_total[5m])) > 0.05
+    expr: sum by (model_name) (rate(inference_objective_request_error_total[5m])) / sum by (model_name) (rate(inference_objective_request_total[5m])) > 0.05
     for: 5m
     labels:
       severity: 'critical'
diff --git a/tools/dashboards/README.md b/tools/dashboards/README.md
index 21282bf..564d8a6 100644
--- a/tools/dashboards/README.md
+++ b/tools/dashboards/README.md
@@ -4,7 +4,7 @@ This documentation provides instructions for setting up grafana dashboards to se
 
 ## Requirements
 
-Please follow [metrics](https://gateway-api-inference-extension.sigs.k8s.io/guides/metrics/?h=metrics) page to configure the proxy to enable all metrics.
+Please follow [metrics](https://gateway-api-inference-extension.sigs.k8s.io/guides/metrics-and-observability/) page to configure the proxy to enable all metrics.
 
 ## Load Inference Extension dashboard into Grafana
 
diff --git a/tools/dashboards/inference_gateway.json b/tools/dashboards/inference_gateway.json
index 244f4ab..949b03f 100644
--- a/tools/dashboards/inference_gateway.json
+++ b/tools/dashboards/inference_gateway.json
@@ -36,7 +36,7 @@
           "showLineNumbers": false,
           "showMiniMap": false
         },
-        "content": "# Inferece Gateway Dashboard\n\nPlease see https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/pkg/epp/metrics for more details of underlying metrics used in the dashboard.",
+        "content": "# Inference Gateway Dashboard\n\nPlease see https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/pkg/epp/metrics for more details of underlying metrics used in the dashboard.",
         "mode": "markdown"
       },
       "pluginVersion": "10.2.4",
@@ -443,7 +443,7 @@
             {
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_model_request_duration_seconds_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_objective_request_duration_seconds_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "includeNullMetadata": false,
               "legendFormat": "95%",
@@ -458,7 +458,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_model_request_duration_seconds_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_objective_request_duration_seconds_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -474,7 +474,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_model_request_duration_seconds_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_objective_request_duration_seconds_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -576,7 +576,7 @@
               "disableTextWrap": false,
               "editorMode": "builder",
               "exemplar": false,
-              "expr": "sum by(model_name, target_model_name) (rate(inference_model_request_total{}[$__rate_interval]))",
+              "expr": "sum by(model_name, target_model_name) (rate(inference_objective_request_total{}[$__rate_interval]))",
               "fullMetaSearch": false,
               "includeNullMetadata": true,
               "interval": "",
@@ -678,7 +678,7 @@
               "disableTextWrap": false,
               "editorMode": "builder",
               "exemplar": false,
-              "expr": "sum by(error_code, model_name, target_model_name) (rate(inference_model_request_error_total[$__rate_interval]))",
+              "expr": "sum by(error_code, model_name, target_model_name) (rate(inference_objective_request_error_total[$__rate_interval]))",
               "fullMetaSearch": false,
               "includeNullMetadata": true,
               "interval": "",
@@ -775,7 +775,7 @@
             {
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_model_request_sizes_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_objective_request_sizes_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "includeNullMetadata": false,
               "legendFormat": "95%",
@@ -790,7 +790,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_model_request_sizes_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_objective_request_sizes_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -806,7 +806,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_model_request_sizes_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_objective_request_sizes_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -903,7 +903,7 @@
             {
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_model_response_sizes_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_objective_response_sizes_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "includeNullMetadata": false,
               "legendFormat": "95%",
@@ -918,7 +918,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_model_response_sizes_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_objective_response_sizes_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -934,7 +934,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_model_response_sizes_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_objective_response_sizes_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -1031,7 +1031,7 @@
             {
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_model_input_tokens_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_objective_input_tokens_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "includeNullMetadata": false,
               "legendFormat": "95%",
@@ -1046,7 +1046,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_model_input_tokens_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_objective_input_tokens_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -1062,7 +1062,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_model_input_tokens_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_objective_input_tokens_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -1159,7 +1159,7 @@
             {
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_model_output_tokens_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.95, sum by(le) (rate(inference_objective_output_tokens_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "includeNullMetadata": false,
               "legendFormat": "95%",
@@ -1174,7 +1174,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_model_output_tokens_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.9, sum by(le) (rate(inference_objective_output_tokens_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -1190,7 +1190,7 @@
               },
               "disableTextWrap": false,
               "editorMode": "builder",
-              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_model_output_tokens_bucket{}[$__rate_interval])))",
+              "expr": "histogram_quantile(0.5, sum by(le) (rate(inference_objective_output_tokens_bucket{}[$__rate_interval])))",
               "fullMetaSearch": false,
               "hide": false,
               "includeNullMetadata": false,
@@ -1204,7 +1204,7 @@
           "type": "timeseries"
         }
       ],
-      "title": "Inference Model",
+      "title": "Inference Objective",
       "type": "row"
     },
     {



Test patch:
diff --git a/apix/v1alpha2/inferencepool_conversion_test.go b/apix/v1alpha2/inferencepool_conversion_test.go
index 847372b..64b222f 100644
--- a/apix/v1alpha2/inferencepool_conversion_test.go
+++ b/apix/v1alpha2/inferencepool_conversion_test.go
@@ -21,6 +21,7 @@ import (
 
 	"github.com/google/go-cmp/cmp"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
 	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
 )
 
@@ -33,8 +34,8 @@ var (
 
 	v1Group       = v1.Group("my-group")
 	v1Kind        = v1.Kind("MyKind")
-	v1FailureMode = v1.ExtensionFailureMode("Deny")
-	v1PortNumber  = v1.PortNumber(9000)
+	v1FailureMode = v1.EndpointPickerFailureMode("Deny")
+	v1Port        = v1.Port{Number: 9000}
 )
 
 func TestInferencePoolConvertTo(t *testing.T) {
@@ -49,7 +50,7 @@ func TestInferencePoolConvertTo(t *testing.T) {
 			src: &InferencePool{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       "InferencePool",
-					APIVersion: "inference.networking.x-k8s.io/v1alpha2",
+					APIVersion: GroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test-pool",
@@ -73,6 +74,12 @@ func TestInferencePoolConvertTo(t *testing.T) {
 						{
 							GatewayRef: ParentGatewayReference{Name: "my-gateway"},
 							Conditions: []metav1.Condition{
+								{ // v1alpha2 default condition is skipped from conversion.
+									Type:               string(v1.InferencePoolConditionAccepted),
+									Status:             metav1.ConditionUnknown,
+									Reason:             string(InferencePoolReasonPending),
+									LastTransitionTime: timestamp,
+								},
 								{
 									Type:               string(InferencePoolConditionAccepted),
 									Status:             metav1.ConditionTrue,
@@ -87,7 +94,7 @@ func TestInferencePoolConvertTo(t *testing.T) {
 			want: &v1.InferencePool{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       "InferencePool",
-					APIVersion: "inference.networking.x-k8s.io/v1alpha2",
+					APIVersion: v1.GroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test-pool",
@@ -100,18 +107,18 @@ func TestInferencePoolConvertTo(t *testing.T) {
 						},
 					},
 					TargetPorts: []v1.Port{{Number: v1.PortNumber(int32(8080))}},
-					ExtensionRef: v1.Extension{
+					EndpointPickerRef: v1.EndpointPickerRef{
 						Group:       &v1Group,
 						Kind:        v1Kind,
 						Name:        "my-epp-service",
-						PortNumber:  v1PortNumber,
+						Port:        &v1Port,
 						FailureMode: v1FailureMode,
 					},
 				},
 				Status: v1.InferencePoolStatus{
-					Parents: []v1.PoolStatus{
+					Parents: []v1.ParentStatus{
 						{
-							GatewayRef: v1.ParentGatewayReference{Name: "my-gateway"},
+							ParentRef: v1.ParentReference{Name: "my-gateway"},
 							Conditions: []metav1.Condition{
 								{
 									Type:               string(v1.InferencePoolConditionAccepted),
@@ -127,11 +134,11 @@ func TestInferencePoolConvertTo(t *testing.T) {
 			wantErr: false,
 		},
 		{
-			name: "conversion from v1alpha2 to v1 with empty extensionRef",
+			name: "conversion from v1alpha2 to v1 with empty extensionRef and default v1alpha2 status condition",
 			src: &InferencePool{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       "InferencePool",
-					APIVersion: "inference.networking.x-k8s.io/v1alpha2",
+					APIVersion: GroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test-pool",
@@ -149,9 +156,9 @@ func TestInferencePoolConvertTo(t *testing.T) {
 							GatewayRef: ParentGatewayReference{Name: "my-gateway"},
 							Conditions: []metav1.Condition{
 								{
-									Type:               string(InferencePoolConditionAccepted),
-									Status:             metav1.ConditionTrue,
-									Reason:             string(InferencePoolReasonAccepted),
+									Type:               string(v1.InferencePoolConditionAccepted),
+									Status:             metav1.ConditionUnknown,
+									Reason:             string(InferencePoolReasonPending),
 									LastTransitionTime: timestamp,
 								},
 							},
@@ -162,7 +169,7 @@ func TestInferencePoolConvertTo(t *testing.T) {
 			want: &v1.InferencePool{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       "InferencePool",
-					APIVersion: "inference.networking.x-k8s.io/v1alpha2",
+					APIVersion: v1.GroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test-pool",
@@ -177,14 +184,202 @@ func TestInferencePoolConvertTo(t *testing.T) {
 					TargetPorts: []v1.Port{{Number: v1.PortNumber(int32(8080))}},
 				},
 				Status: v1.InferencePoolStatus{
-					Parents: []v1.PoolStatus{
+					Parents: []v1.ParentStatus{
+						{
+							ParentRef: v1.ParentReference{Name: "my-gateway"},
+							// Conditions omitted (nil) after dropping the synthetic default.
+						},
+					},
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "v1alpha2 -> v1 maps NotSupportedByGateway to NotSupportedByParent",
+			src: &InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "pool",
+					Namespace: "ns",
+				},
+				Spec: InferencePoolSpec{
+					Selector:         map[LabelKey]LabelValue{"app": "m"},
+					TargetPortNumber: 8080,
+				},
+				Status: InferencePoolStatus{
+					Parents: []PoolStatus{
 						{
-							GatewayRef: v1.ParentGatewayReference{Name: "my-gateway"},
+							GatewayRef: ParentGatewayReference{Name: "gw"},
+							Conditions: []metav1.Condition{
+								{
+									Type:               string(InferencePoolConditionAccepted),
+									Status:             metav1.ConditionFalse,
+									Reason:             string(InferencePoolReasonNotSupportedByGateway),
+									LastTransitionTime: timestamp,
+								},
+							},
+						},
+					},
+				},
+			},
+			want: &v1.InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: v1.GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "pool",
+					Namespace: "ns",
+				},
+				Spec: v1.InferencePoolSpec{
+					Selector: v1.LabelSelector{MatchLabels: map[v1.LabelKey]v1.LabelValue{"app": "m"}},
+					TargetPorts: []v1.Port{
+						{Number: v1.PortNumber(8080)},
+					},
+				},
+				Status: v1.InferencePoolStatus{
+					Parents: []v1.ParentStatus{
+						{
+							ParentRef: v1.ParentReference{Name: "gw"},
 							Conditions: []metav1.Condition{
 								{
 									Type:               string(v1.InferencePoolConditionAccepted),
+									Status:             metav1.ConditionFalse,
+									Reason:             string(v1.InferencePoolReasonNotSupportedByParent),
+									LastTransitionTime: timestamp,
+								},
+							},
+						},
+					},
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "v1alpha2 -> v1 drops synthetic default parent",
+			src: &InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "pool",
+					Namespace: "ns",
+				},
+				Spec: InferencePoolSpec{
+					Selector:         map[LabelKey]LabelValue{"app": "m"},
+					TargetPortNumber: 8080,
+				},
+				Status: InferencePoolStatus{
+					Parents: []PoolStatus{
+						{
+							GatewayRef: func() ParentGatewayReference {
+								k := Kind("Status")
+								return ParentGatewayReference{
+									Kind: &k, Name: "default",
+								}
+							}(),
+							Conditions: []metav1.Condition{
+								{
+									Type:               string(InferencePoolConditionAccepted),
+									Status:             metav1.ConditionUnknown,
+									Reason:             string(InferencePoolReasonPending),
+									LastTransitionTime: timestamp,
+								},
+							},
+						},
+					},
+				},
+			},
+			want: &v1.InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: v1.GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "pool",
+					Namespace: "ns",
+				},
+				Spec: v1.InferencePoolSpec{
+					Selector:    v1.LabelSelector{MatchLabels: map[v1.LabelKey]v1.LabelValue{"app": "m"}},
+					TargetPorts: []v1.Port{{Number: v1.PortNumber(8080)}},
+				},
+				Status: v1.InferencePoolStatus{
+					// All parents dropped -> empty status.
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "v1alpha2 -> v1 drops synthetic default parent but keeps real parent",
+			src: &InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "pool",
+					Namespace: "ns",
+				},
+				Spec: InferencePoolSpec{
+					Selector:         map[LabelKey]LabelValue{"app": "m"},
+					TargetPortNumber: 8080,
+				},
+				Status: InferencePoolStatus{
+					Parents: []PoolStatus{
+						{
+							GatewayRef: func() ParentGatewayReference {
+								k := Kind("Status")
+								return ParentGatewayReference{Kind: &k, Name: "default"}
+							}(),
+							Conditions: []metav1.Condition{
+								{
+									Type:               string(InferencePoolConditionAccepted),
+									Status:             metav1.ConditionUnknown,
+									Reason:             string(InferencePoolReasonPending),
+									LastTransitionTime: timestamp,
+								},
+							},
+						},
+						{
+							GatewayRef: ParentGatewayReference{Name: "real-gw"},
+							Conditions: []metav1.Condition{
+								{
+									Type:               string(InferencePoolConditionResolvedRefs),
 									Status:             metav1.ConditionTrue,
-									Reason:             string(v1.InferencePoolReasonAccepted),
+									Reason:             string(InferencePoolReasonResolvedRefs),
+									LastTransitionTime: timestamp,
+								},
+							},
+						},
+					},
+				},
+			},
+			want: &v1.InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: v1.GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "pool",
+					Namespace: "ns",
+				},
+				Spec: v1.InferencePoolSpec{
+					Selector:    v1.LabelSelector{MatchLabels: map[v1.LabelKey]v1.LabelValue{"app": "m"}},
+					TargetPorts: []v1.Port{{Number: v1.PortNumber(8080)}},
+				},
+				Status: v1.InferencePoolStatus{
+					Parents: []v1.ParentStatus{
+						{
+							ParentRef: v1.ParentReference{Name: "real-gw"},
+							Conditions: []metav1.Condition{
+								{
+									Type:               string(v1.InferencePoolConditionResolvedRefs),
+									Status:             metav1.ConditionTrue,
+									Reason:             string(v1.InferencePoolReasonResolvedRefs),
 									LastTransitionTime: timestamp,
 								},
 							},
@@ -222,7 +417,7 @@ func TestInferencePoolConvertFrom(t *testing.T) {
 			src: &v1.InferencePool{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       "InferencePool",
-					APIVersion: "inference.networking.k8s.io/v1",
+					APIVersion: v1.GroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test-pool",
@@ -235,18 +430,18 @@ func TestInferencePoolConvertFrom(t *testing.T) {
 						},
 					},
 					TargetPorts: []v1.Port{{Number: v1.PortNumber(int32(8080))}},
-					ExtensionRef: v1.Extension{
+					EndpointPickerRef: v1.EndpointPickerRef{
 						Group:       &v1Group,
 						Kind:        v1Kind,
 						Name:        "my-epp-service",
-						PortNumber:  v1PortNumber,
+						Port:        &v1Port,
 						FailureMode: v1FailureMode,
 					},
 				},
 				Status: v1.InferencePoolStatus{
-					Parents: []v1.PoolStatus{
+					Parents: []v1.ParentStatus{
 						{
-							GatewayRef: v1.ParentGatewayReference{Name: "my-gateway"},
+							ParentRef: v1.ParentReference{Name: "my-gateway"},
 							Conditions: []metav1.Condition{
 								{
 									Type:               string(v1.InferencePoolConditionAccepted),
@@ -262,7 +457,7 @@ func TestInferencePoolConvertFrom(t *testing.T) {
 			want: &InferencePool{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       "InferencePool",
-					APIVersion: "inference.networking.k8s.io/v1",
+					APIVersion: GroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test-pool",
@@ -300,11 +495,11 @@ func TestInferencePoolConvertFrom(t *testing.T) {
 			wantErr: false,
 		},
 		{
-			name: "conversion from v1 to v1alpha2 with empty extensionRef",
+			name: "conversion from v1 to v1alpha2 with empty extensionRef and nil status condition",
 			src: &v1.InferencePool{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       "InferencePool",
-					APIVersion: "inference.networking.k8s.io/v1",
+					APIVersion: v1.GroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test-pool",
@@ -319,17 +514,9 @@ func TestInferencePoolConvertFrom(t *testing.T) {
 					TargetPorts: []v1.Port{{Number: v1.PortNumber(int32(8080))}},
 				},
 				Status: v1.InferencePoolStatus{
-					Parents: []v1.PoolStatus{
+					Parents: []v1.ParentStatus{
 						{
-							GatewayRef: v1.ParentGatewayReference{Name: "my-gateway"},
-							Conditions: []metav1.Condition{
-								{
-									Type:               string(v1.InferencePoolConditionAccepted),
-									Status:             metav1.ConditionTrue,
-									Reason:             string(v1.InferencePoolReasonAccepted),
-									LastTransitionTime: timestamp,
-								},
-							},
+							ParentRef: v1.ParentReference{Name: "my-gateway"},
 						},
 					},
 				},
@@ -337,7 +524,7 @@ func TestInferencePoolConvertFrom(t *testing.T) {
 			want: &InferencePool{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       "InferencePool",
-					APIVersion: "inference.networking.k8s.io/v1",
+					APIVersion: GroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test-pool",
@@ -353,11 +540,120 @@ func TestInferencePoolConvertFrom(t *testing.T) {
 					Parents: []PoolStatus{
 						{
 							GatewayRef: ParentGatewayReference{Name: "my-gateway"},
+						},
+					},
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "conversion from v1 to v1alpha2 with empty extensionRef and empty status condition",
+			src: &v1.InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: v1.GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-pool",
+					Namespace: "test-ns",
+				},
+				Spec: v1.InferencePoolSpec{
+					Selector: v1.LabelSelector{
+						MatchLabels: map[v1.LabelKey]v1.LabelValue{
+							"app": "my-model-server",
+						},
+					},
+					TargetPorts: []v1.Port{{Number: v1.PortNumber(int32(8080))}},
+				},
+				Status: v1.InferencePoolStatus{
+					Parents: []v1.ParentStatus{
+						{
+							ParentRef:  v1.ParentReference{Name: "my-gateway"},
+							Conditions: []metav1.Condition{},
+						},
+					},
+				},
+			},
+			want: &InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-pool",
+					Namespace: "test-ns",
+				},
+				Spec: InferencePoolSpec{
+					Selector: map[LabelKey]LabelValue{
+						"app": "my-model-server",
+					},
+					TargetPortNumber: 8080,
+				},
+				Status: InferencePoolStatus{
+					Parents: []PoolStatus{
+						{
+							GatewayRef: ParentGatewayReference{Name: "my-gateway"},
+							Conditions: nil, // Conditions omitted because the converter leaves it nil when v1 had [].
+
+						},
+					},
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "v1 -> v1alpha2 maps NotSupportedByParent to NotSupportedByGateway",
+			src: &v1.InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: v1.GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "pool",
+					Namespace: "ns",
+				},
+				Spec: v1.InferencePoolSpec{
+					Selector:    v1.LabelSelector{MatchLabels: map[v1.LabelKey]v1.LabelValue{"app": "m"}},
+					TargetPorts: []v1.Port{{Number: v1.PortNumber(8080)}},
+				},
+				Status: v1.InferencePoolStatus{
+					Parents: []v1.ParentStatus{
+						{
+							ParentRef: v1.ParentReference{Name: "gw"},
+							Conditions: []metav1.Condition{
+								{
+									Type:               string(v1.InferencePoolConditionAccepted),
+									Status:             metav1.ConditionFalse,
+									Reason:             string(v1.InferencePoolReasonNotSupportedByParent),
+									LastTransitionTime: timestamp,
+								},
+							},
+						},
+					},
+				},
+			},
+			want: &InferencePool{
+				TypeMeta: metav1.TypeMeta{
+					Kind:       "InferencePool",
+					APIVersion: GroupVersion.String(),
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "pool",
+					Namespace: "ns",
+				},
+				Spec: InferencePoolSpec{
+					Selector:         map[LabelKey]LabelValue{"app": "m"},
+					TargetPortNumber: 8080,
+				},
+				Status: InferencePoolStatus{
+					Parents: []PoolStatus{
+						{
+							GatewayRef: ParentGatewayReference{Name: "gw"},
 							Conditions: []metav1.Condition{
 								{
 									Type:               string(InferencePoolConditionAccepted),
-									Status:             metav1.ConditionTrue,
-									Reason:             string(InferencePoolReasonAccepted),
+									Status:             metav1.ConditionFalse,
+									Reason:             string(InferencePoolReasonNotSupportedByGateway),
 									LastTransitionTime: timestamp,
 								},
 							},
diff --git a/conformance/tests/epp_unavailable_fail_open.go b/conformance/tests/epp_unavailable_fail_open.go
index 8af5972..9a831b1 100644
--- a/conformance/tests/epp_unavailable_fail_open.go
+++ b/conformance/tests/epp_unavailable_fail_open.go
@@ -29,7 +29,6 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/conformance/utils/config"
 	k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
 	trafficutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/traffic"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metadata"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/test"
 )
 
@@ -80,7 +79,6 @@ var EppUnAvailableFailOpen = suite.ConformanceTest{
 					Path: path,
 					Headers: map[string]string{
 						test.HeaderTestEppEndPointSelectionKey: targetPodIP,
-						metadata.ObjectiveKey:                  resources.InferenceObjName,
 					},
 					Method:    http.MethodPost,
 					Body:      requestBody,
@@ -108,7 +106,6 @@ var EppUnAvailableFailOpen = suite.ConformanceTest{
 					Path: path,
 					Headers: map[string]string{
 						test.HeaderTestEppEndPointSelectionKey: targetPodIP,
-						metadata.ObjectiveKey:                  resources.InferenceObjName,
 					},
 					Method:    http.MethodPost,
 					Body:      requestBody,
diff --git a/conformance/tests/epp_unavailable_fail_open.yaml b/conformance/tests/epp_unavailable_fail_open.yaml
index 93f3e86..9388a01 100644
--- a/conformance/tests/epp_unavailable_fail_open.yaml
+++ b/conformance/tests/epp_unavailable_fail_open.yaml
@@ -1,15 +1,3 @@
-# --- InferenceObjective Definition ---
-# TODO: remove inferenceObjective dependency https://github.com/kubernetes-sigs/gateway-api-inference-extension/issues/1002
-apiVersion: inference.networking.x-k8s.io/v1alpha2
-kind: InferenceObjective
-metadata:
-  name: conformance-fake-model-server
-  namespace: gateway-conformance-app-backend
-spec:
-  criticality: 2 # Mark criticality high enough to bypass the saturation check since the model server is fake and don't have such metrics. 
-  poolRef:
-    name: secondary-inference-pool
----
 apiVersion: gateway.networking.k8s.io/v1
 kind: HTTPRoute
 metadata:
diff --git a/conformance/tests/gateway_following_epp_routing.go b/conformance/tests/gateway_following_epp_routing.go
index 30a6dde..eaa6181 100644
--- a/conformance/tests/gateway_following_epp_routing.go
+++ b/conformance/tests/gateway_following_epp_routing.go
@@ -33,7 +33,6 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/conformance/resources"
 	k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
 	"sigs.k8s.io/gateway-api-inference-extension/conformance/utils/traffic"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metadata"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/test"
 )
 
@@ -97,7 +96,6 @@ var GatewayFollowingEPPRouting = suite.ConformanceTest{
 					Path: path,
 					Headers: map[string]string{
 						test.HeaderTestEppEndPointSelectionKey: podIPs[i],
-						metadata.ObjectiveKey:                  resources.InferenceObjName,
 					},
 					Method:    http.MethodPost,
 					Body:      requestBody,
@@ -134,7 +132,6 @@ var GatewayFollowingEPPRouting = suite.ConformanceTest{
 				eppHeaderValue := strings.Join(tc.podIPsToBeReturnedByEPP, ",")
 				headers := map[string]string{
 					test.HeaderTestEppEndPointSelectionKey: eppHeaderValue,
-					metadata.ObjectiveKey:                  resources.InferenceObjName,
 				}
 
 				t.Logf("Sending request to %s with EPP header '%s: %s'", gwAddr, test.HeaderTestEppEndPointSelectionKey, eppHeaderValue)
@@ -177,7 +174,7 @@ func assertTrafficOnlyReachesToExpectedPods(t *testing.T, suite *suite.Conforman
 			if err != nil {
 				return fmt.Errorf("failed to roundtrip request: %w", err)
 			}
-			if err := gwhttp.CompareRequest(t, &req, cReq, cRes, expected); err != nil {
+			if err := gwhttp.CompareRoundTrip(t, &req, cReq, cRes, expected); err != nil {
 				return fmt.Errorf("response expectation failed for request: %w", err)
 			}
 
diff --git a/conformance/tests/gateway_following_epp_routing.yaml b/conformance/tests/gateway_following_epp_routing.yaml
index 37b00e7..c4db638 100644
--- a/conformance/tests/gateway_following_epp_routing.yaml
+++ b/conformance/tests/gateway_following_epp_routing.yaml
@@ -1,16 +1,3 @@
-# --- InferenceObjective Definition ---
-# Service for the infra-backend-deployment.
-apiVersion: inference.networking.x-k8s.io/v1alpha2
-kind: InferenceObjective
-metadata:
-  name: conformance-fake-model-server
-  namespace: gateway-conformance-app-backend
-spec:
-  criticality: 2 # Mark criticality high enough to bypass the saturation check since the model server is fake and don't have such metrics.
-  poolRef:
-    name: primary-inference-pool
----
-# --- HTTPRoute for Primary Gateway ---
 apiVersion: gateway.networking.k8s.io/v1
 kind: HTTPRoute
 metadata:
diff --git a/conformance/tests/inferencepool_invalid_epp_service.yaml b/conformance/tests/inferencepool_invalid_epp_service.yaml
index 740e23a..b3dc70e 100644
--- a/conformance/tests/inferencepool_invalid_epp_service.yaml
+++ b/conformance/tests/inferencepool_invalid_epp_service.yaml
@@ -5,10 +5,15 @@ metadata:
   namespace: gateway-conformance-app-backend
 spec:
   selector:
-    app: primary-inference-model-server
-  targetPortNumber: 3000
-  extensionRef:
+    matchLabels:
+      app: primary-inference-model-server
+  targetPorts:
+  - number: 3000
+  endpointPickerRef:
     name: non-existent-epp-svc
+    kind: Service
+    port:
+      number: 9002
 ---
 apiVersion: gateway.networking.k8s.io/v1
 kind: HTTPRoute
diff --git a/pkg/bbr/handlers/request_test.go b/pkg/bbr/handlers/request_test.go
index e597953..9e408fd 100644
--- a/pkg/bbr/handlers/request_test.go
+++ b/pkg/bbr/handlers/request_test.go
@@ -206,7 +206,7 @@ func TestHandleRequestBody(t *testing.T) {
 	bbr_success_total{} 1
 	`
 
-	if err := metricsutils.GatherAndCompare(crmetrics.Registry, strings.NewReader(wantMetrics), "inference_model_request_total"); err != nil {
+	if err := metricsutils.GatherAndCompare(crmetrics.Registry, strings.NewReader(wantMetrics), "inference_objective_request_total"); err != nil {
 		t.Error(err)
 	}
 }
diff --git a/pkg/epp/config/loader/configloader_test.go b/pkg/epp/config/loader/configloader_test.go
index 0701f96..b0b0741 100644
--- a/pkg/epp/config/loader/configloader_test.go
+++ b/pkg/epp/config/loader/configloader_test.go
@@ -73,7 +73,7 @@ func TestLoadRawConfiguration(t *testing.T) {
 			},
 			{
 				Type:       test2Type,
-				Parameters: json.RawMessage("{\"hashBlockSize\":32}"),
+				Parameters: json.RawMessage("{\"blockSize\":32}"),
 			},
 			{
 				Name: "testPicker",
@@ -175,7 +175,7 @@ func TestLoadRawConfigurationWithDefaults(t *testing.T) {
 			{
 				Name:       test2Type,
 				Type:       test2Type,
-				Parameters: json.RawMessage("{\"hashBlockSize\":32}"),
+				Parameters: json.RawMessage("{\"blockSize\":32}"),
 			},
 			{
 				Name: "testPicker",
@@ -443,6 +443,7 @@ func registerNeededPlgugins() {
 	plugins.Register(prefix.PrefixCachePluginType, prefix.PrefixCachePluginFactory)
 	plugins.Register(picker.MaxScorePickerType, picker.MaxScorePickerFactory)
 	plugins.Register(picker.RandomPickerType, picker.RandomPickerFactory)
+	plugins.Register(picker.WeightedRandomPickerType, picker.WeightedRandomPickerFactory)
 	plugins.Register(profile.SingleProfileHandlerType, profile.SingleProfileHandlerFactory)
 }
 
@@ -463,7 +464,7 @@ plugins:
   type: test-profile-handler
 - type: test-two
   parameters:
-    hashBlockSize: 32
+    blockSize: 32
 - name: testPicker
   type: test-picker
 schedulingProfiles:
@@ -663,7 +664,6 @@ func (f *test1) Filter(_ context.Context, _ *types.CycleState, _ *types.LLMReque
 
 // compile-time type validation
 var _ framework.Scorer = &test2{}
-var _ framework.PostCycle = &test2{}
 
 type test2 struct {
 	typedName plugins.TypedName
@@ -683,8 +683,6 @@ func (m *test2) Score(_ context.Context, _ *types.CycleState, _ *types.LLMReques
 	return map[types.Pod]float64{}
 }
 
-func (m *test2) PostCycle(_ context.Context, _ *types.CycleState, _ *types.ProfileRunResult) {}
-
 // compile-time type validation
 var _ framework.Picker = &testPicker{}
 
@@ -769,7 +767,7 @@ plugins:
 - name: prefixCacheScorer
   type: prefix-cache-scorer
   parameters:
-    hashBlockSize: 32
+    blockSize: 32
 - name: maxScorePicker
   type: max-score-picker
 - name: profileHandler
@@ -794,7 +792,7 @@ plugins:
 - name: prefixCacheScorer
   type: prefix-cache-scorer
   parameters:
-    hashBlockSize: 32
+    blockSize: 32
 schedulingProfiles:
 - name: default
   plugins:
@@ -828,7 +826,7 @@ plugins:
 - name: prefixCacheScorer
   type: prefix-cache-scorer
   parameters:
-    hashBlockSize: asdf
+    blockSize: asdf
 schedulingProfiles:
 - name: default
   plugins:
diff --git a/pkg/epp/controller/inferencepool_reconciler_test.go b/pkg/epp/controller/inferencepool_reconciler_test.go
index 48d5083..553fcc7 100644
--- a/pkg/epp/controller/inferencepool_reconciler_test.go
+++ b/pkg/epp/controller/inferencepool_reconciler_test.go
@@ -24,6 +24,7 @@ import (
 	"github.com/google/go-cmp/cmp"
 	"github.com/google/go-cmp/cmp/cmpopts"
 	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -81,9 +82,9 @@ func TestInferencePoolReconciler(t *testing.T) {
 		Namespace("pool1-ns").
 		Selector(selector_v1).
 		TargetPorts(8080).
-		ExtensionRef("epp-service").ObjRef()
+		EndpointPickerRef("epp-service").ObjRef()
 	pool1.SetGroupVersionKind(gvk)
-	pool2 := utiltest.MakeInferencePool("pool2").Namespace("pool2-ns").ExtensionRef("epp-service").ObjRef()
+	pool2 := utiltest.MakeInferencePool("pool2").Namespace("pool2-ns").EndpointPickerRef("epp-service").ObjRef()
 	pool2.SetGroupVersionKind(gvk)
 
 	// Set up the scheme.
@@ -180,7 +181,9 @@ type diffStoreParams struct {
 
 func diffStore(datastore datastore.Datastore, params diffStoreParams) string {
 	gotPool, _ := datastore.PoolGet()
-	if diff := cmp.Diff(params.wantPool, gotPool); diff != "" {
+	// controller-runtime fake client may not populate TypeMeta (APIVersion/Kind).
+	// Ignore it when comparing pools.
+	if diff := cmp.Diff(params.wantPool, gotPool, cmpopts.IgnoreTypes(metav1.TypeMeta{})); diff != "" {
 		return "pool:" + diff
 	}
 
@@ -333,7 +336,10 @@ func xDiffStore(t *testing.T, datastore datastore.Datastore, params xDiffStorePa
 	if err != nil {
 		t.Fatalf("failed to convert InferencePool to XInferencePool: %v", err)
 	}
-	if diff := cmp.Diff(params.wantPool, gotXPool); diff != "" {
+
+	// controller-runtime fake client may not populate TypeMeta (APIVersion/Kind).
+	// Ignore it when comparing pools.
+	if diff := cmp.Diff(params.wantPool, gotXPool, cmpopts.IgnoreTypes(metav1.TypeMeta{})); diff != "" {
 		return "pool:" + diff
 	}
 
diff --git a/pkg/epp/flowcontrol/config_test.go b/pkg/epp/flowcontrol/config_test.go
new file mode 100644
index 0000000..713abee
--- /dev/null
+++ b/pkg/epp/flowcontrol/config_test.go
@@ -0,0 +1,91 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package flowcontrol
+
+import (
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/controller"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/registry"
+)
+
+func TestConfig_ValidateAndApplyDefaults(t *testing.T) {
+	t.Parallel()
+
+	// A minimal valid registry config, which is required for the success case.
+	validRegistryConfig := registry.Config{
+		PriorityBands: []registry.PriorityBandConfig{
+			{Priority: 1, PriorityName: "TestBand"},
+		},
+	}
+
+	testCases := []struct {
+		name          string
+		input         Config
+		expectErr     bool
+		expectedErrIs error
+	}{
+		{
+			name: "ShouldSucceed_WhenSubConfigsAreValid",
+			input: Config{
+				Controller: controller.Config{},
+				Registry:   validRegistryConfig,
+			},
+			expectErr: false,
+		},
+		{
+			name: "ShouldFail_WhenControllerConfigIsInvalid",
+			input: Config{
+				Controller: controller.Config{
+					DefaultRequestTTL: -1 * time.Second,
+				},
+				Registry: validRegistryConfig,
+			},
+			expectErr: true,
+		},
+		{
+			name: "ShouldFail_WhenRegistryConfigIsInvalid",
+			input: Config{
+				Controller: controller.Config{},
+				Registry: registry.Config{
+					PriorityBands: []registry.PriorityBandConfig{},
+				},
+			},
+			expectErr: true,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
+			originalInput := tc.input
+			validatedCfg, err := tc.input.ValidateAndApplyDefaults()
+
+			if tc.expectErr {
+				require.Error(t, err, "expected an error but got nil")
+			} else {
+				require.NoError(t, err, "expected no error but got: %v", err)
+				require.NotNil(t, validatedCfg, "validatedCfg should not be nil on success")
+			}
+
+			assert.Equal(t, originalInput, tc.input, "input config should not be mutated")
+		})
+	}
+}
diff --git a/pkg/epp/flowcontrol/controller/config_test.go b/pkg/epp/flowcontrol/controller/config_test.go
new file mode 100644
index 0000000..710df9f
--- /dev/null
+++ b/pkg/epp/flowcontrol/controller/config_test.go
@@ -0,0 +1,135 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package controller
+
+import (
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestConfig_ValidateAndApplyDefaults(t *testing.T) {
+	t.Parallel()
+
+	testCases := []struct {
+		name          string
+		input         Config
+		expectErr     bool
+		expectedCfg   Config
+		shouldDefault bool
+	}{
+		{
+			name: "ValidConfig_NoChanges",
+			input: Config{
+				DefaultRequestTTL:               10 * time.Second,
+				ExpiryCleanupInterval:           2 * time.Second,
+				ProcessorReconciliationInterval: 10 * time.Second,
+				EnqueueChannelBufferSize:        200,
+			},
+			expectErr: false,
+			expectedCfg: Config{
+				DefaultRequestTTL:               10 * time.Second,
+				ExpiryCleanupInterval:           2 * time.Second,
+				ProcessorReconciliationInterval: 10 * time.Second,
+				EnqueueChannelBufferSize:        200,
+			},
+		},
+		{
+			name:      "EmptyConfig_ShouldApplyDefaults",
+			input:     Config{},
+			expectErr: false,
+			expectedCfg: Config{
+				DefaultRequestTTL:               0,
+				ExpiryCleanupInterval:           defaultExpiryCleanupInterval,
+				ProcessorReconciliationInterval: defaultProcessorReconciliationInterval,
+				EnqueueChannelBufferSize:        defaultEnqueueChannelBufferSize,
+			},
+			shouldDefault: true,
+		},
+		{
+			name:      "NegativeDefaultRequestTTL_Invalid",
+			input:     Config{DefaultRequestTTL: -1},
+			expectErr: true,
+		},
+		{
+			name:      "NegativeExpiryCleanupInterval_Invalid",
+			input:     Config{ExpiryCleanupInterval: -1},
+			expectErr: true,
+		},
+		{
+			name:      "NegativeProcessorReconciliationInterval_Invalid",
+			input:     Config{ProcessorReconciliationInterval: -1},
+			expectErr: true,
+		},
+		{
+			name:      "NegativeEnqueueChannelBufferSize_Invalid",
+			input:     Config{EnqueueChannelBufferSize: -1},
+			expectErr: true,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
+			originalInput := tc.input.deepCopy()
+			validatedCfg, err := tc.input.ValidateAndApplyDefaults()
+
+			if tc.expectErr {
+				require.Error(t, err, "expected an error but got nil")
+				assert.Nil(t, validatedCfg, "validatedCfg should be nil on error")
+			} else {
+				require.NoError(t, err, "expected no error but got: %v", err)
+				require.NotNil(t, validatedCfg, "validatedCfg should not be nil on success")
+				assert.Equal(t, tc.expectedCfg, *validatedCfg, "validatedCfg should match expected config")
+
+				// Ensure the original config is not mutated.
+				assert.Equal(t, *originalInput, tc.input, "input config should not be mutated")
+			}
+		})
+	}
+}
+
+func TestConfig_DeepCopy(t *testing.T) {
+	t.Parallel()
+
+	t.Run("ShouldReturnNil_ForNilReceiver", func(t *testing.T) {
+		t.Parallel()
+		var nilConfig *Config
+		assert.Nil(t, nilConfig.deepCopy(), "Deep copy of a nil config should be nil")
+	})
+
+	t.Run("ShouldCreateIdenticalButSeparateObject", func(t *testing.T) {
+		t.Parallel()
+		original := &Config{
+			DefaultRequestTTL:               1 * time.Second,
+			ExpiryCleanupInterval:           2 * time.Second,
+			ProcessorReconciliationInterval: 3 * time.Second,
+			EnqueueChannelBufferSize:        4,
+		}
+		clone := original.deepCopy()
+
+		require.NotSame(t, original, clone, "Clone should be a new object in memory")
+		assert.Equal(t, *original, *clone, "Cloned object should have identical values")
+
+		// Modify the clone and ensure the original is unchanged.
+		clone.DefaultRequestTTL = 99 * time.Second
+		assert.NotEqual(t, original.DefaultRequestTTL, clone.DefaultRequestTTL,
+			"Original should not be mutated after clone is changed")
+	})
+}
diff --git a/pkg/epp/flowcontrol/controller/controller_test.go b/pkg/epp/flowcontrol/controller/controller_test.go
new file mode 100644
index 0000000..c832e2d
--- /dev/null
+++ b/pkg/epp/flowcontrol/controller/controller_test.go
@@ -0,0 +1,829 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package controller
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"sync"
+	"sync/atomic"
+	"testing"
+	"time"
+
+	"github.com/go-logr/logr"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"k8s.io/utils/clock"
+	testclock "k8s.io/utils/clock/testing"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts/mocks"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/controller/internal"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
+	frameworkmocks "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/mocks"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
+	typesmocks "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types/mocks"
+)
+
+// --- Test Harness & Fixtures ---
+
+// withClock returns a test-only option to inject a clock.
+// test-only
+func withClock(c clock.WithTicker) flowControllerOption {
+	return func(fc *FlowController) {
+		fc.clock = c
+	}
+}
+
+// withRegistryClient returns a test-only option to inject a mock or fake registry client.
+// test-only
+func withRegistryClient(client registryClient) flowControllerOption {
+	return func(fc *FlowController) {
+		fc.registry = client
+	}
+}
+
+// withShardProcessorFactory returns a test-only option to inject a processor factory.
+// test-only
+func withShardProcessorFactory(factory shardProcessorFactory) flowControllerOption {
+	return func(fc *FlowController) {
+		fc.shardProcessorFactory = factory
+	}
+}
+
+// testHarness holds the `FlowController` and its dependencies under test.
+type testHarness struct {
+	fc                   *FlowController
+	cfg                  Config
+	mockRegistry         *mockRegistryClient
+	mockDetector         *mocks.MockSaturationDetector
+	mockClock            *testclock.FakeClock
+	mockProcessorFactory *mockShardProcessorFactory
+}
+
+// newUnitHarness creates a test environment with a mock processor factory, suitable for focused unit tests of the
+// controller's logic. It starts the controller's run loop and returns a cancel function to stop it.
+func newUnitHarness(t *testing.T, ctx context.Context, cfg Config, registry *mockRegistryClient) *testHarness {
+	t.Helper()
+	mockDetector := &mocks.MockSaturationDetector{}
+	mockClock := testclock.NewFakeClock(time.Now())
+	mockProcessorFactory := &mockShardProcessorFactory{
+		processors: make(map[string]*mockShardProcessor),
+	}
+	opts := []flowControllerOption{
+		withRegistryClient(registry),
+		withClock(mockClock),
+		withShardProcessorFactory(mockProcessorFactory.new),
+	}
+	fc, err := NewFlowController(ctx, cfg, registry, mockDetector, logr.Discard(), opts...)
+	require.NoError(t, err, "failed to create FlowController for unit test harness")
+
+	h := &testHarness{
+		fc:                   fc,
+		cfg:                  cfg,
+		mockRegistry:         registry,
+		mockDetector:         mockDetector,
+		mockClock:            mockClock,
+		mockProcessorFactory: mockProcessorFactory,
+	}
+	return h
+}
+
+// newIntegrationHarness creates a test environment that uses real `ShardProcessor`s, suitable for integration tests
+// validating the controller-processor interaction.
+func newIntegrationHarness(t *testing.T, ctx context.Context, cfg Config, registry *mockRegistryClient) *testHarness {
+	t.Helper()
+	mockDetector := &mocks.MockSaturationDetector{}
+	mockClock := testclock.NewFakeClock(time.Now())
+	opts := []flowControllerOption{
+		withRegistryClient(registry),
+		withClock(mockClock),
+	}
+	fc, err := NewFlowController(ctx, cfg, registry, mockDetector, logr.Discard(), opts...)
+	require.NoError(t, err, "failed to create FlowController for integration test harness")
+
+	h := &testHarness{
+		fc:           fc,
+		cfg:          cfg,
+		mockRegistry: registry,
+		mockDetector: mockDetector,
+		mockClock:    mockClock,
+	}
+	return h
+}
+
+// mockActiveFlowConnection is a local mock for the `contracts.ActiveFlowConnection` interface.
+type mockActiveFlowConnection struct {
+	contracts.ActiveFlowConnection
+	ActiveShardsV []contracts.RegistryShard
+}
+
+func (m *mockActiveFlowConnection) ActiveShards() []contracts.RegistryShard {
+	return m.ActiveShardsV
+}
+
+// mockRegistryClient is a mock for the private `registryClient` interface.
+type mockRegistryClient struct {
+	contracts.FlowRegistryObserver
+	contracts.FlowRegistryDataPlane
+	WithConnectionFunc func(key types.FlowKey, fn func(conn contracts.ActiveFlowConnection) error) error
+	ShardStatsFunc     func() []contracts.ShardStats
+}
+
+func (m *mockRegistryClient) WithConnection(
+	key types.FlowKey,
+	fn func(conn contracts.ActiveFlowConnection) error,
+) error {
+	if m.WithConnectionFunc != nil {
+		return m.WithConnectionFunc(key, fn)
+	}
+	return fn(&mockActiveFlowConnection{})
+}
+
+func (m *mockRegistryClient) ShardStats() []contracts.ShardStats {
+	if m.ShardStatsFunc != nil {
+		return m.ShardStatsFunc()
+	}
+	return nil
+}
+
+// mockShardProcessor is a mock for the internal `shardProcessor` interface.
+type mockShardProcessor struct {
+	SubmitFunc        func(item *internal.FlowItem) error
+	SubmitOrBlockFunc func(ctx context.Context, item *internal.FlowItem) error
+	runCtx            context.Context
+	runCtxMu          sync.RWMutex
+	runStarted        chan struct{}
+}
+
+func (m *mockShardProcessor) Submit(item *internal.FlowItem) error {
+	if m.SubmitFunc != nil {
+		return m.SubmitFunc(item)
+	}
+	return nil
+}
+
+func (m *mockShardProcessor) SubmitOrBlock(ctx context.Context, item *internal.FlowItem) error {
+	if m.SubmitOrBlockFunc != nil {
+		return m.SubmitOrBlockFunc(ctx, item)
+	}
+	return nil
+}
+
+func (m *mockShardProcessor) Run(ctx context.Context) {
+	m.runCtxMu.Lock()
+	m.runCtx = ctx
+	m.runCtxMu.Unlock()
+	if m.runStarted != nil {
+		close(m.runStarted)
+	}
+	<-ctx.Done()
+}
+
+func (m *mockShardProcessor) Context() context.Context {
+	m.runCtxMu.RLock()
+	defer m.runCtxMu.RUnlock()
+	return m.runCtx
+}
+
+// mockShardProcessorFactory allows tests to inject specific `mockShardProcessor` instances.
+type mockShardProcessorFactory struct {
+	mu         sync.Mutex
+	processors map[string]*mockShardProcessor
+}
+
+func (f *mockShardProcessorFactory) new(
+	shard contracts.RegistryShard,
+	_ contracts.SaturationDetector,
+	_ clock.Clock,
+	_ time.Duration,
+	_ int,
+	_ logr.Logger,
+) shardProcessor {
+	f.mu.Lock()
+	defer f.mu.Unlock()
+	if proc, ok := f.processors[shard.ID()]; ok {
+		return proc
+	}
+	// Return a default mock processor if one is not registered.
+	return &mockShardProcessor{}
+}
+
+// stubManagedQueue is a simple stub for the `contracts.ManagedQueue`  interface.
+type stubManagedQueue struct {
+	contracts.ManagedQueue
+	byteSizeV uint64
+}
+
+func (s *stubManagedQueue) ByteSize() uint64 { return s.byteSizeV }
+
+func (s *stubManagedQueue) FlowQueueAccessor() framework.FlowQueueAccessor {
+	return &frameworkmocks.MockFlowQueueAccessor{ByteSizeV: s.byteSizeV}
+}
+
+// mockShardBuilder is a fixture to declaratively build mock `contracts.RegistryShard` for tests.
+type mockShardBuilder struct {
+	id       string
+	byteSize uint64
+}
+
+func newMockShard(id string) *mockShardBuilder {
+	return &mockShardBuilder{id: id}
+}
+
+func (b *mockShardBuilder) withByteSize(size uint64) *mockShardBuilder {
+	b.byteSize = size
+	return b
+}
+
+func (b *mockShardBuilder) build() contracts.RegistryShard {
+	return &mocks.MockRegistryShard{
+		IDFunc: func() string { return b.id },
+		ManagedQueueFunc: func(_ types.FlowKey) (contracts.ManagedQueue, error) {
+			return &stubManagedQueue{byteSizeV: b.byteSize}, nil
+		},
+	}
+}
+
+var defaultFlowKey = types.FlowKey{ID: "test-flow", Priority: 100}
+
+func newTestRequest(ctx context.Context, key types.FlowKey) *typesmocks.MockFlowControlRequest {
+	return &typesmocks.MockFlowControlRequest{
+		Ctx:       ctx,
+		FlowKeyV:  key,
+		ByteSizeV: 100,
+		IDV:       "req-" + key.ID,
+	}
+}
+
+// --- Test Cases ---
+
+func TestFlowController_EnqueueAndWait(t *testing.T) {
+	t.Parallel()
+
+	t.Run("Rejections", func(t *testing.T) {
+		t.Parallel()
+
+		t.Run("OnNilRequest", func(t *testing.T) {
+			t.Parallel()
+			h := newUnitHarness(t, t.Context(), Config{}, &mockRegistryClient{})
+
+			outcome, err := h.fc.EnqueueAndWait(nil)
+			require.Error(t, err, "EnqueueAndWait must reject a nil request")
+			assert.Equal(t, "request cannot be nil", err.Error())
+			assert.Equal(t, types.QueueOutcomeRejectedOther, outcome, "outcome should be QueueOutcomeRejectedOther")
+		})
+
+		t.Run("OnControllerShutdown", func(t *testing.T) {
+			t.Parallel()
+			ctx, cancel := context.WithCancel(t.Context())
+			h := newUnitHarness(t, ctx, Config{}, &mockRegistryClient{})
+			cancel() // Immediately stop the controller.
+
+			req := newTestRequest(context.Background(), defaultFlowKey)
+			outcome, err := h.fc.EnqueueAndWait(req)
+			require.Error(t, err, "EnqueueAndWait must reject requests if controller is not running")
+			assert.ErrorIs(t, err, types.ErrRejected, "error should wrap ErrRejected")
+			assert.ErrorIs(t, err, types.ErrFlowControllerNotRunning, "error should wrap ErrFlowControllerNotRunning")
+			assert.Equal(t, types.QueueOutcomeRejectedOther, outcome, "outcome should be QueueOutcomeRejectedOther")
+		})
+
+		t.Run("OnNoShardsAvailable", func(t *testing.T) {
+			t.Parallel()
+			h := newUnitHarness(t, t.Context(), Config{}, &mockRegistryClient{})
+
+			req := newTestRequest(context.Background(), defaultFlowKey)
+			outcome, err := h.fc.EnqueueAndWait(req)
+			require.Error(t, err, "EnqueueAndWait must reject requests if no shards are available")
+			assert.ErrorIs(t, err, types.ErrRejected, "error should wrap ErrRejected")
+			assert.Equal(t, types.QueueOutcomeRejectedCapacity, outcome, "outcome should be QueueOutcomeRejectedCapacity")
+		})
+
+		t.Run("OnRegistryConnectionError", func(t *testing.T) {
+			t.Parallel()
+			mockRegistry := &mockRegistryClient{}
+			h := newUnitHarness(t, t.Context(), Config{}, mockRegistry)
+
+			expectedErr := errors.New("connection failed")
+			mockRegistry.WithConnectionFunc = func(
+				_ types.FlowKey,
+				_ func(conn contracts.ActiveFlowConnection) error,
+			) error {
+				return expectedErr
+			}
+
+			req := newTestRequest(context.Background(), defaultFlowKey)
+			outcome, err := h.fc.EnqueueAndWait(req)
+			require.Error(t, err, "EnqueueAndWait must reject requests if registry connection fails")
+			assert.ErrorIs(t, err, types.ErrRejected, "error should wrap ErrRejected")
+			assert.ErrorIs(t, err, expectedErr, "error should wrap the underlying connection error")
+			assert.Equal(t, types.QueueOutcomeRejectedOther, outcome, "outcome should be QueueOutcomeRejectedOther")
+		})
+
+		t.Run("PanicsOnManagedQueueError", func(t *testing.T) {
+			t.Parallel()
+			mockRegistry := &mockRegistryClient{}
+			h := newUnitHarness(t, t.Context(), Config{}, mockRegistry)
+
+			faultyShard := &mocks.MockRegistryShard{
+				IDFunc: func() string { return "faulty-shard" },
+				ManagedQueueFunc: func(_ types.FlowKey) (contracts.ManagedQueue, error) {
+					return nil, errors.New("queue retrieval failed")
+				},
+			}
+			mockRegistry.WithConnectionFunc = func(
+				_ types.FlowKey,
+				fn func(conn contracts.ActiveFlowConnection) error,
+			) error {
+				return fn(&mockActiveFlowConnection{ActiveShardsV: []contracts.RegistryShard{faultyShard}})
+			}
+
+			req := newTestRequest(context.Background(), defaultFlowKey)
+			assert.Panics(t, func() {
+				_, _ = h.fc.EnqueueAndWait(req)
+			}, "EnqueueAndWait did not panic as expected on a ManagedQueue error")
+		})
+	})
+
+	t.Run("Distribution", func(t *testing.T) {
+		t.Parallel()
+
+		testCases := []struct {
+			name            string
+			shards          []contracts.RegistryShard
+			setupProcessors func(t *testing.T, h *testHarness)
+			expectedOutcome types.QueueOutcome
+			expectErr       bool
+		}{
+			{
+				name:   "SubmitSucceeds_NonBlocking_WithSingleActiveShard",
+				shards: []contracts.RegistryShard{newMockShard("shard-A").build()},
+				setupProcessors: func(t *testing.T, h *testHarness) {
+					h.mockProcessorFactory.processors["shard-A"] = &mockShardProcessor{
+						SubmitFunc: func(item *internal.FlowItem) error {
+							go item.Finalize(types.QueueOutcomeDispatched, nil)
+							return nil
+						},
+					}
+				},
+				expectedOutcome: types.QueueOutcomeDispatched,
+			},
+			{
+				name: "DistributesToLeastLoadedShard_WithMultipleActiveShards",
+				shards: []contracts.RegistryShard{
+					newMockShard("shard-A").withByteSize(1000).build(),
+					newMockShard("shard-B").withByteSize(100).build(),
+				},
+				setupProcessors: func(t *testing.T, h *testHarness) {
+					h.mockProcessorFactory.processors["shard-A"] = &mockShardProcessor{
+						SubmitFunc: func(_ *internal.FlowItem) error {
+							t.Error("Submit was called on the more loaded shard (shard-A), which is incorrect")
+							return internal.ErrProcessorBusy
+						},
+					}
+					h.mockProcessorFactory.processors["shard-B"] = &mockShardProcessor{
+						SubmitFunc: func(item *internal.FlowItem) error {
+							go item.Finalize(types.QueueOutcomeDispatched, nil)
+							return nil
+						},
+					}
+				},
+				expectedOutcome: types.QueueOutcomeDispatched,
+			},
+			{
+				name: "SubmitSucceeds_AfterBlocking_WithAllProcessorsBusy",
+				shards: []contracts.RegistryShard{
+					newMockShard("shard-A").withByteSize(1000).build(),
+					newMockShard("shard-B").withByteSize(100).build(),
+				},
+				setupProcessors: func(t *testing.T, h *testHarness) {
+					h.mockProcessorFactory.processors["shard-A"] = &mockShardProcessor{
+						SubmitFunc: func(_ *internal.FlowItem) error { return internal.ErrProcessorBusy },
+					}
+					h.mockProcessorFactory.processors["shard-B"] = &mockShardProcessor{
+						SubmitFunc: func(_ *internal.FlowItem) error { return internal.ErrProcessorBusy },
+						SubmitOrBlockFunc: func(_ context.Context, item *internal.FlowItem) error {
+							go item.Finalize(types.QueueOutcomeDispatched, nil)
+							return nil
+						},
+					}
+				},
+				expectedOutcome: types.QueueOutcomeDispatched,
+			},
+			{
+				name:   "Rejects_AfterBlocking_WithAllProcessorsRemainingBusy",
+				shards: []contracts.RegistryShard{newMockShard("shard-A").build()},
+				setupProcessors: func(t *testing.T, h *testHarness) {
+					h.mockProcessorFactory.processors["shard-A"] = &mockShardProcessor{
+						SubmitFunc:        func(_ *internal.FlowItem) error { return internal.ErrProcessorBusy },
+						SubmitOrBlockFunc: func(_ context.Context, _ *internal.FlowItem) error { return context.DeadlineExceeded },
+					}
+				},
+				expectedOutcome: types.QueueOutcomeRejectedCapacity,
+				expectErr:       true,
+			},
+		}
+
+		for _, tc := range testCases {
+			t.Run(tc.name, func(t *testing.T) {
+				t.Parallel()
+				mockRegistry := &mockRegistryClient{}
+				h := newUnitHarness(t, t.Context(), Config{}, mockRegistry)
+				mockRegistry.WithConnectionFunc = func(
+					_ types.FlowKey,
+					fn func(conn contracts.ActiveFlowConnection) error,
+				) error {
+					return fn(&mockActiveFlowConnection{ActiveShardsV: tc.shards})
+				}
+				tc.setupProcessors(t, h)
+				outcome, err := h.fc.EnqueueAndWait(newTestRequest(context.Background(), defaultFlowKey))
+				if tc.expectErr {
+					require.Error(t, err, "expected an error but got nil")
+				} else {
+					require.NoError(t, err, "expected no error but got: %v", err)
+				}
+				assert.Equal(t, tc.expectedOutcome, outcome, "outcome did not match expected value")
+			})
+		}
+	})
+
+	t.Run("Retry", func(t *testing.T) {
+		t.Parallel()
+
+		t.Run("Rejects_OnRequestContextCancelledWhileBlocking", func(t *testing.T) {
+			t.Parallel()
+			mockRegistry := &mockRegistryClient{
+				WithConnectionFunc: func(
+					_ types.FlowKey,
+					fn func(conn contracts.ActiveFlowConnection,
+					) error) error {
+					return fn(&mockActiveFlowConnection{
+						ActiveShardsV: []contracts.RegistryShard{newMockShard("shard-A").build()},
+					})
+				},
+			}
+			h := newUnitHarness(t, t.Context(), Config{}, mockRegistry)
+			h.mockProcessorFactory.processors["shard-A"] = &mockShardProcessor{
+				SubmitFunc:        func(_ *internal.FlowItem) error { return internal.ErrProcessorBusy },
+				SubmitOrBlockFunc: func(ctx context.Context, _ *internal.FlowItem) error { <-ctx.Done(); return ctx.Err() },
+			}
+			reqCtx, cancelReq := context.WithCancel(context.Background())
+			go func() { time.Sleep(50 * time.Millisecond); cancelReq() }()
+
+			outcome, err := h.fc.EnqueueAndWait(newTestRequest(reqCtx, defaultFlowKey))
+
+			require.Error(t, err, "EnqueueAndWait must fail when context is cancelled during a blocking submit")
+			assert.ErrorIs(t, err, types.ErrRejected, "error should wrap ErrRejected")
+			assert.ErrorIs(t, err, context.Canceled, "error should wrap the underlying ctx.Err()")
+			assert.Equal(t, types.QueueOutcomeRejectedCapacity, outcome, "outcome should be QueueOutcomeRejectedCapacity")
+		})
+
+		t.Run("RetriesAndSucceeds_OnProcessorReportsShardDraining", func(t *testing.T) {
+			t.Parallel()
+			var callCount atomic.Int32
+			mockRegistry := &mockRegistryClient{
+				WithConnectionFunc: func(
+					_ types.FlowKey,
+					fn func(conn contracts.ActiveFlowConnection) error,
+				) error {
+					attempt := callCount.Add(1)
+					shardA := newMockShard("shard-A").withByteSize(100).build()
+					shardB := newMockShard("shard-B").withByteSize(1000).build()
+					if attempt == 1 {
+						return fn(&mockActiveFlowConnection{ActiveShardsV: []contracts.RegistryShard{shardA, shardB}})
+					}
+					return fn(&mockActiveFlowConnection{ActiveShardsV: []contracts.RegistryShard{shardB}})
+				},
+			}
+			h := newUnitHarness(t, t.Context(), Config{}, mockRegistry)
+			h.mockProcessorFactory.processors["shard-A"] = &mockShardProcessor{
+				SubmitFunc: func(item *internal.FlowItem) error {
+					go item.Finalize(types.QueueOutcomeRejectedOther, contracts.ErrShardDraining)
+					return nil
+				},
+			}
+			h.mockProcessorFactory.processors["shard-B"] = &mockShardProcessor{
+				SubmitFunc: func(item *internal.FlowItem) error {
+					go item.Finalize(types.QueueOutcomeDispatched, nil)
+					return nil
+				},
+			}
+
+			outcome, err := h.fc.EnqueueAndWait(newTestRequest(context.Background(), defaultFlowKey))
+			require.NoError(t, err, "EnqueueAndWait must succeed after retrying on a healthy shard")
+			assert.Equal(t, types.QueueOutcomeDispatched, outcome, "outcome should be QueueOutcomeDispatched")
+			assert.Equal(t, int32(2), callCount.Load(), "registry must be consulted for Active shards on each retry attempt")
+		})
+	})
+}
+
+func TestFlowController_Lifecycle(t *testing.T) {
+	t.Parallel()
+
+	t.Run("Reconciliation", func(t *testing.T) {
+		t.Parallel()
+
+		mockRegistry := &mockRegistryClient{
+			// Configure the mock registry to report the new state without the stale shard.
+			ShardStatsFunc: func() []contracts.ShardStats {
+				return []contracts.ShardStats{{ID: "shard-A"}}
+			}}
+		h := newUnitHarness(t, t.Context(), Config{}, mockRegistry)
+
+		// Pre-populate the controller with initial workers.
+		initialShards := []string{"shard-A", "stale-shard"}
+		for _, shardID := range initialShards {
+			currentShardID := shardID
+			h.mockProcessorFactory.processors[currentShardID] = &mockShardProcessor{runStarted: make(chan struct{})}
+			shard := &mocks.MockRegistryShard{IDFunc: func() string { return currentShardID }}
+			h.fc.getOrStartWorker(shard)
+		}
+		require.Len(t, h.mockProcessorFactory.processors, 2, "pre-condition: initial workers not set up correctly")
+
+		// Wait for all workers to have started and set their contexts before proceeding with the test.
+		for id, p := range h.mockProcessorFactory.processors {
+			proc := p
+			select {
+			case <-proc.runStarted:
+				// Success
+			case <-time.After(2 * time.Second):
+				t.Fatalf("timed out waiting for worker %s to start", id)
+			}
+		}
+
+		// Manually trigger the reconciliation loop logic.
+		h.fc.reconcileProcessors()
+
+		t.Run("StaleWorkerIsCancelled", func(t *testing.T) {
+			staleProc := h.mockProcessorFactory.processors["stale-shard"]
+			require.NotNil(t, staleProc.Context(), "precondition: stale processor context should have been captured")
+			select {
+			case <-staleProc.Context().Done():
+				// Success
+			case <-time.After(100 * time.Millisecond):
+				t.Error("context of removed worker must be cancelled")
+			}
+		})
+
+		t.Run("ActiveWorkerIsNotCancelled", func(t *testing.T) {
+			activeProc := h.mockProcessorFactory.processors["shard-A"]
+			require.NotNil(t, activeProc.Context(), "precondition: active processor context should have been captured")
+			select {
+			case <-activeProc.Context().Done():
+				t.Error("context of remaining worker must not be cancelled")
+			default:
+				// Success
+			}
+		})
+
+		t.Run("WorkerMapIsUpdated", func(t *testing.T) {
+			_, ok := h.fc.workers.Load("stale-shard")
+			assert.False(t, ok, "stale worker must be removed from the controller's map")
+			_, ok = h.fc.workers.Load("shard-A")
+			assert.True(t, ok, "active worker must remain in the controller's map")
+		})
+	})
+
+	t.Run("Reconciliation_IsTriggeredByTicker", func(t *testing.T) {
+		t.Parallel()
+		reconciliationInterval := 10 * time.Second
+		mockRegistry := &mockRegistryClient{}
+
+		var reconcileCount atomic.Int32
+		mockRegistry.ShardStatsFunc = func() []contracts.ShardStats {
+			reconcileCount.Add(1)
+			return nil
+		}
+
+		h := newUnitHarness(t, t.Context(), Config{ProcessorReconciliationInterval: reconciliationInterval}, mockRegistry)
+
+		// Wait for the reconciliation loop to start and create the ticker.
+		// This prevents a race where the clock is stepped before the ticker is registered.
+		require.Eventually(t, h.mockClock.HasWaiters, time.Second, 10*time.Millisecond, "ticker was not created")
+
+		// Advance the clock to trigger the next reconciliation.
+		h.mockClock.Step(reconciliationInterval)
+
+		assert.Eventually(t, func() bool {
+			return reconcileCount.Load() == 1
+		}, time.Second, 10*time.Millisecond, "reconciliation was not triggered by the ticker")
+
+		// Advance the clock again to ensure it continues to fire.
+		h.mockClock.Step(reconciliationInterval)
+		assert.Eventually(t, func() bool {
+			return reconcileCount.Load() == 2
+		}, time.Second, 10*time.Millisecond, "reconciliation did not fire on the second tick")
+	})
+
+	t.Run("WorkerCreationRace", func(t *testing.T) {
+		t.Parallel()
+
+		// This test requires manual control over the shard processor factory to deterministically create a race.
+		factoryEntered := make(chan *mockShardProcessor, 2)
+		continueFactory := make(chan struct{})
+
+		h := newUnitHarness(t, t.Context(), Config{}, &mockRegistryClient{})
+		h.fc.shardProcessorFactory = func(
+			shard contracts.RegistryShard,
+			_ contracts.SaturationDetector,
+			_ clock.Clock,
+			_ time.Duration,
+			_ int,
+			_ logr.Logger,
+		) shardProcessor {
+			// This factory function will be called by `startNewWorker`.
+			// We use channels to pause execution here, allowing two goroutines to enter this function before one "wins"
+			// the `LoadOrStore` race.
+			proc := &mockShardProcessor{runStarted: make(chan struct{})}
+			factoryEntered <- proc
+			<-continueFactory
+			return proc
+		}
+
+		shard := newMockShard("race-shard").build()
+		var wg sync.WaitGroup
+		wg.Add(2)
+
+		// Start two goroutines that will race to create the same worker.
+		go func() {
+			defer wg.Done()
+			h.fc.getOrStartWorker(shard)
+		}()
+		go func() {
+			defer wg.Done()
+			h.fc.getOrStartWorker(shard)
+		}()
+
+		// Wait for both goroutines to have entered the factory and created a processor.
+		// This confirms they both missed the initial `workers.Load` check.
+		proc1 := <-factoryEntered
+		proc2 := <-factoryEntered
+
+		// Unblock both goroutines, allowing them to race to `workers.LoadOrStore`.
+		close(continueFactory)
+		wg.Wait()
+
+		// One processor "won" and was stored, the other "lost" and should have been cancelled.
+		actual, ok := h.fc.workers.Load("race-shard")
+		require.True(t, ok, "a worker should have been stored in the map")
+
+		storedWorker := actual.(*managedWorker)
+		winnerProc := storedWorker.processor.(*mockShardProcessor)
+
+		var loserProc *mockShardProcessor
+		if winnerProc == proc1 {
+			loserProc = proc2
+		} else {
+			loserProc = proc1
+		}
+
+		// Wait for the `Run` method to be called on the winning processor to ensure its context is available.
+		select {
+		case <-winnerProc.runStarted:
+		// Success.
+		case <-time.After(1 * time.Second):
+			t.Fatal("timed out waiting for winning worker to start")
+		}
+
+		// The winning processor's context must remain active.
+		require.NotNil(t, winnerProc.Context(), "winner's context should not be nil")
+		select {
+		case <-winnerProc.Context().Done():
+			t.Error("context of the winning worker should not be cancelled")
+		default:
+			// Success
+		}
+
+		// The losing processor's `Run` method must not be called, and its context should be nil.
+		select {
+		case <-loserProc.runStarted:
+			t.Error("Run was called on the losing worker, but it should not have been")
+		default:
+			// Success
+		}
+		assert.Nil(t, loserProc.Context(), "loser's context should be nil as Run is never called")
+	})
+}
+
+func TestFlowController_Concurrency(t *testing.T) {
+	const (
+		numShards     = 4
+		numGoroutines = 50
+		numRequests   = 200
+	)
+
+	// Set up a realistic registry that vends real components to the processor.
+	mockRegistry := &mockRegistryClient{}
+	shards := make([]contracts.RegistryShard, numShards)
+	queues := make(map[string]contracts.ManagedQueue)
+	for i := range numShards {
+		shardID := fmt.Sprintf("shard-%d", i)
+		queues[shardID] = &mocks.MockManagedQueue{FlowKeyV: defaultFlowKey} // Use the high-fidelity mock queue.
+		shards[i] = &mocks.MockRegistryShard{
+			IDFunc: func() string { return shardID },
+			ManagedQueueFunc: func(_ types.FlowKey) (contracts.ManagedQueue, error) {
+				return queues[shardID], nil
+			},
+			AllOrderedPriorityLevelsFunc: func() []int { return []int{100} },
+			PriorityBandAccessorFunc: func(priority int) (framework.PriorityBandAccessor, error) {
+				if priority == 100 {
+					return &frameworkmocks.MockPriorityBandAccessor{
+						PriorityNameV: "high",
+						PriorityV:     100,
+						IterateQueuesFunc: func(f func(framework.FlowQueueAccessor) bool) {
+							f(queues[shardID].FlowQueueAccessor())
+						},
+					}, nil
+				}
+				return nil, fmt.Errorf("unexpected priority %d", priority)
+			},
+			IntraFlowDispatchPolicyFunc: func(_ types.FlowKey) (framework.IntraFlowDispatchPolicy, error) {
+				return &frameworkmocks.MockIntraFlowDispatchPolicy{
+					SelectItemFunc: func(qa framework.FlowQueueAccessor) (types.QueueItemAccessor, error) {
+						return qa.PeekHead()
+					},
+				}, nil
+			},
+			InterFlowDispatchPolicyFunc: func(_ int) (framework.InterFlowDispatchPolicy, error) {
+				return &frameworkmocks.MockInterFlowDispatchPolicy{
+					SelectQueueFunc: func(band framework.PriorityBandAccessor) (framework.FlowQueueAccessor, error) {
+						return queues[shardID].FlowQueueAccessor(), nil
+					},
+				}, nil
+			},
+			StatsFunc: func() contracts.ShardStats {
+				return contracts.ShardStats{
+					ID:            shardID,
+					TotalLen:      uint64(queues[shardID].Len()),
+					TotalByteSize: queues[shardID].ByteSize(),
+					PerPriorityBandStats: map[int]contracts.PriorityBandStats{
+						100: {
+							Len:           uint64(queues[shardID].Len()),
+							ByteSize:      queues[shardID].ByteSize(),
+							CapacityBytes: 1e9, // Effectively unlimited capacity
+						},
+					},
+				}
+			},
+		}
+	}
+	mockRegistry.WithConnectionFunc = func(_ types.FlowKey, fn func(conn contracts.ActiveFlowConnection) error) error {
+		return fn(&mockActiveFlowConnection{ActiveShardsV: shards})
+	}
+	mockRegistry.ShardStatsFunc = func() []contracts.ShardStats {
+		stats := make([]contracts.ShardStats, len(shards))
+		for i, shard := range shards {
+			stats[i] = shard.Stats()
+		}
+		return stats
+	}
+	h := newIntegrationHarness(t, t.Context(), Config{
+		// Use a generous buffer to prevent flakes in the test due to transient queuing delays.
+		EnqueueChannelBufferSize: numRequests,
+		DefaultRequestTTL:        1 * time.Second,
+		ExpiryCleanupInterval:    100 * time.Millisecond,
+	}, mockRegistry)
+
+	var wg sync.WaitGroup
+	wg.Add(numGoroutines)
+	outcomes := make(chan types.QueueOutcome, numRequests)
+	for range numGoroutines {
+		go func() {
+			defer wg.Done()
+			for range numRequests / numGoroutines {
+				req := newTestRequest(logr.NewContext(context.Background(), logr.Discard()), defaultFlowKey)
+				outcome, err := h.fc.EnqueueAndWait(req)
+				if err != nil {
+					// Use `t.Errorf` for concurrent tests to avoid halting execution on a single failure.
+					t.Errorf("EnqueueAndWait failed unexpectedly: %v", err)
+				}
+				outcomes <- outcome
+			}
+		}()
+	}
+	wg.Wait()
+	close(outcomes)
+
+	successCount := 0
+	for outcome := range outcomes {
+		if outcome == types.QueueOutcomeDispatched {
+			successCount++
+		}
+	}
+	require.Equal(t, numRequests, successCount, "all concurrent requests should be dispatched successfully")
+}
diff --git a/pkg/epp/flowcontrol/controller/internal/filter_test.go b/pkg/epp/flowcontrol/controller/internal/filter_test.go
deleted file mode 100644
index ceff9e8..0000000
--- a/pkg/epp/flowcontrol/controller/internal/filter_test.go
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
-Copyright 2025 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package internal
-
-import (
-	"context"
-	"sort"
-	"testing"
-
-	"github.com/go-logr/logr"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts/mocks"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
-	frameworkmocks "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/mocks"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
-)
-
-func TestNewSaturationFilter(t *testing.T) {
-	t.Parallel()
-
-	testCases := []struct {
-		name                  string
-		isSaturated           bool
-		expectShouldPause     bool
-		expectFilteredBandNil bool
-	}{
-		{
-			name:                  "should not pause or filter when system is not saturated",
-			isSaturated:           false,
-			expectShouldPause:     false,
-			expectFilteredBandNil: true, // nil band signals the fast path
-		},
-		{
-			name:                  "should pause when system is saturated",
-			isSaturated:           true,
-			expectShouldPause:     true,
-			expectFilteredBandNil: true,
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			t.Parallel()
-
-			// --- ARRANGE ---
-			mockSD := &mocks.MockSaturationDetector{IsSaturatedFunc: func(ctx context.Context) bool { return tc.isSaturated }}
-			filter := NewSaturationFilter(mockSD)
-			require.NotNil(t, filter, "NewSaturationFilter should not return nil")
-
-			mockBand := &frameworkmocks.MockPriorityBandAccessor{}
-
-			// --- ACT ---
-			filteredBand, shouldPause := filter(context.Background(), mockBand, logr.Discard())
-
-			// --- ASSERT ---
-			assert.Equal(t, tc.expectShouldPause, shouldPause, "The filter's pause signal should match the expected value")
-
-			if tc.expectFilteredBandNil {
-				assert.Nil(t, filteredBand, "Expected filtered band to be nil")
-			} else {
-				assert.NotNil(t, filteredBand, "Expected a non-nil filtered band")
-			}
-		})
-	}
-}
-
-func TestSubsetPriorityBandAccessor(t *testing.T) {
-	t.Parallel()
-
-	// --- ARRANGE ---
-	// Setup a mock original accessor that knows about three flows.
-	flowAKey := types.FlowKey{ID: "flow-a", Priority: 10}
-	flowBKey := types.FlowKey{ID: "flow-b", Priority: 10}
-	flowCKey := types.FlowKey{ID: "flow-c", Priority: 10}
-
-	mockQueueA := &frameworkmocks.MockFlowQueueAccessor{FlowKeyV: flowAKey}
-	mockQueueB := &frameworkmocks.MockFlowQueueAccessor{FlowKeyV: flowBKey}
-	mockQueueC := &frameworkmocks.MockFlowQueueAccessor{FlowKeyV: flowCKey}
-
-	originalAccessor := &frameworkmocks.MockPriorityBandAccessor{
-		PriorityV:     10,
-		PriorityNameV: "High",
-		FlowKeysFunc: func() []types.FlowKey {
-			return []types.FlowKey{flowAKey, flowBKey, flowCKey}
-		},
-		QueueFunc: func(id string) framework.FlowQueueAccessor {
-			switch id {
-			case "flow-a":
-				return mockQueueA
-			case "flow-b":
-				return mockQueueB
-			case "flow-c":
-				return mockQueueC
-			}
-			return nil
-		},
-		IterateQueuesFunc: func(callback func(queue framework.FlowQueueAccessor) bool) {
-			if !callback(mockQueueA) {
-				return
-			}
-			if !callback(mockQueueB) {
-				return
-			}
-			callback(mockQueueC)
-		},
-	}
-
-	// Create a subset view that only allows two of the flows.
-	allowedFlows := []types.FlowKey{flowAKey, flowCKey}
-	subsetAccessor := newSubsetPriorityBandAccessor(originalAccessor, allowedFlows)
-	require.NotNil(t, subsetAccessor, "newSubsetPriorityBandAccessor should not return nil")
-
-	t.Run("should pass through priority and name", func(t *testing.T) {
-		t.Parallel()
-		assert.Equal(t, uint(10), subsetAccessor.Priority(), "Priority() should pass through from the original accessor")
-		assert.Equal(t, "High", subsetAccessor.PriorityName(),
-			"PriorityName() should pass through from the original accessor")
-	})
-
-	t.Run("should only return allowed flow keys", func(t *testing.T) {
-		t.Parallel()
-		flowKeys := subsetAccessor.FlowKeys()
-		// Sort for consistent comparison, as the pre-computed slice order is not guaranteed.
-		sort.Slice(flowKeys, func(i, j int) bool {
-			return flowKeys[i].ID < flowKeys[j].ID
-		})
-		assert.Equal(t, []types.FlowKey{flowAKey, flowCKey}, flowKeys, "FlowKeys() should only return the allowed subset")
-	})
-
-	t.Run("should only return queues for allowed flows", func(t *testing.T) {
-		t.Parallel()
-		assert.Same(t, mockQueueA, subsetAccessor.Queue("flow-a"), "Should return queue for allowed flow 'a'")
-		assert.Nil(t, subsetAccessor.Queue("flow-b"), "Should not return queue for disallowed flow 'b'")
-		assert.Same(t, mockQueueC, subsetAccessor.Queue("flow-c"), "Should return queue for allowed flow 'c'")
-	})
-
-	t.Run("should only iterate over allowed queues", func(t *testing.T) {
-		t.Parallel()
-		var iterated []string
-		subsetAccessor.IterateQueues(func(queue framework.FlowQueueAccessor) bool {
-			iterated = append(iterated, queue.FlowKey().ID)
-			return true
-		})
-		// Sort for consistent comparison, as iteration order is not guaranteed.
-		sort.Strings(iterated)
-		assert.Equal(t, []string{"flow-a", "flow-c"}, iterated, "IterateQueues() should only visit allowed flows")
-	})
-
-	t.Run("should stop iteration if callback returns false", func(t *testing.T) {
-		t.Parallel()
-		var iterated []string
-		subsetAccessor.IterateQueues(func(queue framework.FlowQueueAccessor) bool {
-			iterated = append(iterated, queue.FlowKey().ID)
-			return false // Exit after the first item.
-		})
-		assert.Len(t, iterated, 1, "Iteration should have stopped after one item")
-	})
-}
diff --git a/pkg/epp/flowcontrol/controller/internal/item_test.go b/pkg/epp/flowcontrol/controller/internal/item_test.go
index d50aaed..1f713e9 100644
--- a/pkg/epp/flowcontrol/controller/internal/item_test.go
+++ b/pkg/epp/flowcontrol/controller/internal/item_test.go
@@ -18,6 +18,7 @@ package internal
 
 import (
 	"context"
+	"errors"
 	"testing"
 	"time"
 
@@ -28,25 +29,47 @@ import (
 	typesmocks "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types/mocks"
 )
 
-func TestItem(t *testing.T) {
+func TestFlowItem_New(t *testing.T) {
 	t.Parallel()
+	req := typesmocks.NewMockFlowControlRequest(100, "req-1", types.FlowKey{}, context.Background())
 
-	t.Run("should correctly set and get handle", func(t *testing.T) {
-		t.Parallel()
-		item := &flowItem{}
-		handle := &typesmocks.MockQueueItemHandle{}
-		item.SetHandle(handle)
-		assert.Same(t, handle, item.Handle(), "Handle() should retrieve the same handle instance set by SetHandle()")
-	})
-
-	t.Run("should have a non-finalized state upon creation", func(t *testing.T) {
-		t.Parallel()
-		key := types.FlowKey{ID: "flow-a", Priority: 10}
-		req := typesmocks.NewMockFlowControlRequest(100, "req-1", key, context.Background())
-		item := NewItem(req, time.Minute, time.Now())
-		require.NotNil(t, item, "NewItem should not return nil")
-		outcome, err := item.FinalState()
-		assert.Equal(t, types.QueueOutcomeNotYetFinalized, outcome, "A new item's outcome should be NotYetFinalized")
-		assert.NoError(t, err, "A new item should have a nil error")
-	})
+	item := NewItem(req, time.Minute, time.Now())
+
+	require.NotNil(t, item, "NewItem should not return a nil item")
+	assert.False(t, item.isFinalized(), "a new item must not be in a finalized state")
+	select {
+	case <-item.Done():
+		t.Fatal("Done() channel for a new item must block, but it was closed")
+	default:
+		// This is the expected path, as the channel would have blocked.
+	}
+}
+
+func TestFlowItem_Handle(t *testing.T) {
+	t.Parallel()
+	item := &FlowItem{}
+	handle := &typesmocks.MockQueueItemHandle{}
+	item.SetHandle(handle)
+	assert.Same(t, handle, item.Handle(), "Handle() must retrieve the identical handle instance set by SetHandle()")
+}
+
+func TestFlowItem_Finalize_Idempotency(t *testing.T) {
+	t.Parallel()
+	req := typesmocks.NewMockFlowControlRequest(100, "req-1", types.FlowKey{}, context.Background())
+	item := NewItem(req, time.Minute, time.Now())
+	expectedErr := errors.New("first-error")
+
+	item.Finalize(types.QueueOutcomeEvictedTTL, expectedErr)
+	item.Finalize(types.QueueOutcomeDispatched, nil) // Should take no effect
+
+	assert.True(t, item.isFinalized(), "item must be in a finalized state after a call to finalize()")
+	select {
+	case finalState, ok := <-item.Done():
+		require.True(t, ok, "Done() channel should be readable with a value, not just closed")
+		assert.Equal(t, types.QueueOutcomeEvictedTTL, finalState.Outcome,
+			"the outcome from Done() must match the first finalized outcome")
+		assert.Equal(t, expectedErr, finalState.Err, "the error from Done() must match the first finalized error")
+	case <-time.After(50 * time.Millisecond):
+		t.Fatal("Done() channel must not block after finalization")
+	}
 }
diff --git a/pkg/epp/flowcontrol/controller/internal/processor_test.go b/pkg/epp/flowcontrol/controller/internal/processor_test.go
index 67657a9..4c31d7a 100644
--- a/pkg/epp/flowcontrol/controller/internal/processor_test.go
+++ b/pkg/epp/flowcontrol/controller/internal/processor_test.go
@@ -14,29 +14,6 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-//
-// A Note on the Testing Strategy for `ShardProcessor`
-//
-// The `ShardProcessor` is a complex concurrent orchestrator. Testing it with concrete implementations would lead to
-// flaky, non-deterministic tests. Therefore, we use a high-fidelity `testHarness` with stateful mocks to enable
-// reliable and deterministic testing. This is a deliberate and necessary choice for several key reasons:
-//
-// 1.  Deterministic Race Simulation: The harness allows us to pause mock execution at critical moments, making it
-//     possible to deterministically simulate and verify the processor's behavior during race conditions (e.g., the
-//     dispatch vs. expiry race). This is impossible with concrete implementations without resorting to unreliable
-//     sleeps.
-//
-// 2.  Failure Mode Simulation: We can trigger specific, on-demand errors from dependencies to verify the processor's
-//     resilience and complex error-handling logic (e.g., the `errIntraFlow` circuit breaker).
-//
-// 3.  Interaction and Isolation Testing: Mocks allow us to isolate the `ShardProcessor` from its dependencies. This
-//     ensures that tests are verifying the processor's orchestration logic (i.e., that it calls its dependencies
-//     correctly) and are not affected by confounding bugs in those dependencies.
-//
-// In summary, this is a prerequisite for reliably testing a concurrent engine, not just a simple data
-// structure.
-//
-
 package internal
 
 import (
@@ -44,7 +21,7 @@ import (
 	"errors"
 	"fmt"
 	"os"
-	"slices"
+	"sort"
 	"sync"
 	"sync/atomic"
 	"testing"
@@ -53,9 +30,11 @@ import (
 	"github.com/go-logr/logr"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	testclock "k8s.io/utils/clock/testing"
 	"sigs.k8s.io/controller-runtime/pkg/log"
 	"sigs.k8s.io/controller-runtime/pkg/log/zap"
 
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts/mocks"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
@@ -79,28 +58,6 @@ func TestMain(m *testing.M) {
 	os.Exit(m.Run())
 }
 
-// mockClock allows for controlling time in tests.
-type mockClock struct {
-	mu          sync.Mutex
-	currentTime time.Time
-}
-
-func newMockClock() *mockClock {
-	return &mockClock{currentTime: time.Now()}
-}
-
-func (c *mockClock) Now() time.Time {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	return c.currentTime
-}
-
-func (c *mockClock) Advance(d time.Duration) {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	c.currentTime = c.currentTime.Add(d)
-}
-
 // testHarness provides a unified, mock-based testing environment for the ShardProcessor. It centralizes all mock state
 // and provides helper methods for setting up tests and managing the processor's lifecycle.
 type testHarness struct {
@@ -114,15 +71,16 @@ type testHarness struct {
 	startSignal chan struct{}
 
 	// Core components under test
-	processor *ShardProcessor
-	mockClock *mockClock
-	logger    logr.Logger
+	processor          *ShardProcessor
+	clock              *testclock.FakeClock
+	logger             logr.Logger
+	saturationDetector *mocks.MockSaturationDetector
 
 	// --- Centralized Mock State ---
 	// The harness's mutex protects the single source of truth for all mock state.
 	mu            sync.Mutex
 	queues        map[types.FlowKey]*mocks.MockManagedQueue
-	priorityFlows map[uint][]types.FlowKey // Key: `priority`
+	priorityFlows map[int][]types.FlowKey // Key: `priority`
 
 	// Customizable policy logic for tests to override.
 	interFlowPolicySelectQueue func(band framework.PriorityBandAccessor) (framework.FlowQueueAccessor, error)
@@ -133,13 +91,14 @@ type testHarness struct {
 func newTestHarness(t *testing.T, expiryCleanupInterval time.Duration) *testHarness {
 	t.Helper()
 	h := &testHarness{
-		t:                 t,
-		MockRegistryShard: &mocks.MockRegistryShard{},
-		mockClock:         newMockClock(),
-		logger:            logr.Discard(),
-		startSignal:       make(chan struct{}),
-		queues:            make(map[types.FlowKey]*mocks.MockManagedQueue),
-		priorityFlows:     make(map[uint][]types.FlowKey),
+		t:                  t,
+		MockRegistryShard:  &mocks.MockRegistryShard{},
+		clock:              testclock.NewFakeClock(time.Now()),
+		logger:             logr.Discard(),
+		saturationDetector: &mocks.MockSaturationDetector{},
+		startSignal:        make(chan struct{}),
+		queues:             make(map[types.FlowKey]*mocks.MockManagedQueue),
+		priorityFlows:      make(map[int][]types.FlowKey),
 	}
 
 	// Wire up the harness to provide the mock implementations for the shard's dependencies.
@@ -153,22 +112,17 @@ func newTestHarness(t *testing.T, expiryCleanupInterval time.Duration) *testHarn
 	h.StatsFunc = func() contracts.ShardStats {
 		return contracts.ShardStats{
 			TotalCapacityBytes: 1e9,
-			PerPriorityBandStats: map[uint]contracts.PriorityBandStats{
+			PerPriorityBandStats: map[int]contracts.PriorityBandStats{
 				testFlow.Priority: {CapacityBytes: 1e9},
 			},
 		}
 	}
 
-	// Use a default pass-through filter.
-	filter := func(
-		ctx context.Context,
-		band framework.PriorityBandAccessor,
-		logger logr.Logger,
-	) (framework.PriorityBandAccessor, bool) {
-		return nil, false
-	}
-	h.processor = NewShardProcessor(h, filter, h.mockClock, expiryCleanupInterval, h.logger)
+	h.processor = NewShardProcessor(h, h.saturationDetector, h.clock, expiryCleanupInterval, 100, h.logger)
 	require.NotNil(t, h.processor, "NewShardProcessor should not return nil")
+
+	t.Cleanup(func() { h.Stop() })
+
 	return h
 }
 
@@ -202,23 +156,23 @@ func (h *testHarness) Stop() {
 }
 
 // waitForFinalization blocks until an item is finalized or a timeout is reached.
-func (h *testHarness) waitForFinalization(item *flowItem) (types.QueueOutcome, error) {
+func (h *testHarness) waitForFinalization(item *FlowItem) (types.QueueOutcome, error) {
 	h.t.Helper()
 	select {
-	case <-item.Done():
-		return item.FinalState()
+	case finalState := <-item.Done():
+		return finalState.Outcome, finalState.Err
 	case <-time.After(testWaitTimeout):
 		h.t.Fatalf("Timed out waiting for item %q to be finalized", item.OriginalRequest().ID())
 		return types.QueueOutcomeNotYetFinalized, nil
 	}
 }
 
-// newTestItem creates a new flowItem for testing purposes.
-func (h *testHarness) newTestItem(id string, key types.FlowKey, ttl time.Duration) *flowItem {
+// newTestItem creates a new FlowItem for testing purposes.
+func (h *testHarness) newTestItem(id string, key types.FlowKey, ttl time.Duration) *FlowItem {
 	h.t.Helper()
 	ctx := log.IntoContext(context.Background(), h.logger)
 	req := typesmocks.NewMockFlowControlRequest(100, id, key, ctx)
-	return NewItem(req, ttl, h.mockClock.Now())
+	return NewItem(req, ttl, h.clock.Now())
 }
 
 // addQueue centrally registers a new mock queue for a given flow, ensuring all harness components are aware of it.
@@ -226,13 +180,9 @@ func (h *testHarness) addQueue(key types.FlowKey) *mocks.MockManagedQueue {
 	h.t.Helper()
 	h.mu.Lock()
 	defer h.mu.Unlock()
-
 	mockQueue := &mocks.MockManagedQueue{FlowKeyV: key}
 	h.queues[key] = mockQueue
-
-	// Add the key to the correct priority band, creating the band if needed.
 	h.priorityFlows[key.Priority] = append(h.priorityFlows[key.Priority], key)
-
 	return mockQueue
 }
 
@@ -249,20 +199,23 @@ func (h *testHarness) managedQueue(key types.FlowKey) (contracts.ManagedQueue, e
 }
 
 // allOrderedPriorityLevels provides the mock implementation for the `RegistryShard` interface.
-func (h *testHarness) allOrderedPriorityLevels() []uint {
+func (h *testHarness) allOrderedPriorityLevels() []int {
 	h.mu.Lock()
 	defer h.mu.Unlock()
-	prios := make([]uint, 0, len(h.priorityFlows))
+	prios := make([]int, 0, len(h.priorityFlows))
 	for p := range h.priorityFlows {
 		prios = append(prios, p)
 	}
-	slices.Sort(prios)
+	sort.Slice(prios, func(i, j int) bool {
+		return prios[i] > prios[j]
+	})
+
 	return prios
 }
 
 // priorityBandAccessor provides the mock implementation for the `RegistryShard` interface. It acts as a factory for a
 // fully-configured, stateless mock that is safe for concurrent use.
-func (h *testHarness) priorityBandAccessor(p uint) (framework.PriorityBandAccessor, error) {
+func (h *testHarness) priorityBandAccessor(p int) (framework.PriorityBandAccessor, error) {
 	band := &frameworkmocks.MockPriorityBandAccessor{PriorityV: p}
 
 	// Safely get a snapshot of the flow IDs under a lock.
@@ -288,7 +241,7 @@ func (h *testHarness) priorityBandAccessor(p uint) (framework.PriorityBandAccess
 }
 
 // interFlowDispatchPolicy provides the mock implementation for the `contracts.RegistryShard` interface.
-func (h *testHarness) interFlowDispatchPolicy(p uint) (framework.InterFlowDispatchPolicy, error) {
+func (h *testHarness) interFlowDispatchPolicy(p int) (framework.InterFlowDispatchPolicy, error) {
 	policy := &frameworkmocks.MockInterFlowDispatchPolicy{}
 	// If the test provided a custom implementation, use it.
 	if h.interFlowPolicySelectQueue != nil {
@@ -331,9 +284,9 @@ func (h *testHarness) intraFlowDispatchPolicy(types.FlowKey) (framework.IntraFlo
 func TestShardProcessor(t *testing.T) {
 	t.Parallel()
 
-	// Lifecycle tests use the processor's main `Run` loop to verify the complete end-to-end lifecycle of a request, from
+	// Integration tests use the processor's main `Run` loop to verify the complete end-to-end lifecycle of a request, from
 	// `Enqueue` to its final outcome.
-	t.Run("Lifecycle", func(t *testing.T) {
+	t.Run("Integration", func(t *testing.T) {
 		t.Parallel()
 
 		t.Run("should dispatch item successfully", func(t *testing.T) {
@@ -341,12 +294,11 @@ func TestShardProcessor(t *testing.T) {
 			// --- ARRANGE ---
 			h := newTestHarness(t, testCleanupTick)
 			item := h.newTestItem("req-dispatch-success", testFlow, testTTL)
-			h.addQueue(types.FlowKey{ID: testFlow.ID, Priority: testFlow.Priority})
+			h.addQueue(testFlow)
 
 			// --- ACT ---
 			h.Start()
-			defer h.Stop()
-			h.processor.Enqueue(item)
+			require.NoError(t, h.processor.Submit(item), "precondition: Submit should not fail")
 			h.Go()
 
 			// --- ASSERT ---
@@ -362,15 +314,14 @@ func TestShardProcessor(t *testing.T) {
 			item := h.newTestItem("req-capacity-reject", testFlow, testTTL)
 			h.addQueue(testFlow)
 			h.StatsFunc = func() contracts.ShardStats {
-				return contracts.ShardStats{PerPriorityBandStats: map[uint]contracts.PriorityBandStats{
+				return contracts.ShardStats{PerPriorityBandStats: map[int]contracts.PriorityBandStats{
 					testFlow.Priority: {CapacityBytes: 50}, // 50 is less than item size of 100
 				}}
 			}
 
 			// --- ACT ---
 			h.Start()
-			defer h.Stop()
-			h.processor.Enqueue(item)
+			require.NoError(t, h.processor.Submit(item), "precondition: Submit should not fail")
 			h.Go()
 
 			// --- ASSERT ---
@@ -393,7 +344,7 @@ func TestShardProcessor(t *testing.T) {
 			// --- ACT ---
 			h.Start()
 			defer h.Stop()
-			h.processor.Enqueue(item)
+			require.NoError(t, h.processor.Submit(item), "precondition: Submit should not fail")
 			h.Go()
 
 			// --- ASSERT ---
@@ -413,15 +364,14 @@ func TestShardProcessor(t *testing.T) {
 			// --- ACT ---
 			h.Start()
 			h.Go()
-			// Stop the processor, then immediately try to enqueue.
-			h.Stop()
-			h.processor.Enqueue(item)
+			h.Stop() // Stop the processor, then immediately try to enqueue.
+			require.NoError(t, h.processor.Submit(item), "precondition: Submit should not fail, even on shutdown")
 
 			// --- ASSERT ---
 			outcome, err := h.waitForFinalization(item)
 			assert.Equal(t, types.QueueOutcomeRejectedOther, outcome, "The outcome should be RejectedOther")
 			require.Error(t, err, "An eviction on shutdown should produce an error")
-			assert.ErrorIs(t, err, types.ErrFlowControllerShutdown, "The error should be of type ErrFlowControllerShutdown")
+			assert.ErrorIs(t, err, types.ErrFlowControllerNotRunning, "The error should be of type ErrFlowControllerNotRunning")
 		})
 
 		t.Run("should evict item on TTL expiry via background cleanup", func(t *testing.T) {
@@ -433,13 +383,12 @@ func TestShardProcessor(t *testing.T) {
 
 			// --- ACT ---
 			h.Start()
-			defer h.Stop()
-			h.processor.Enqueue(item)
+			require.NoError(t, h.processor.Submit(item), "precondition: Submit should not fail")
 			h.Go()
 
-			// Let time pass for the item to expire and for the background cleanup to run.
-			h.mockClock.Advance(testShortTTL * 2)
-			time.Sleep(testCleanupTick * 3) // Allow the cleanup goroutine time to run.
+			h.clock.Step(testShortTTL * 2) // Let time pass for the item to expire.
+			// Manually invoke the cleanup logic to simulate a tick of the cleanup loop deterministically.
+			h.processor.cleanupExpired(h.clock.Now())
 
 			// --- ASSERT ---
 			outcome, err := h.waitForFinalization(item)
@@ -448,52 +397,22 @@ func TestShardProcessor(t *testing.T) {
 			assert.ErrorIs(t, err, types.ErrTTLExpired, "The error should be of type ErrTTLExpired")
 		})
 
-		t.Run("should evict item at moment of dispatch if TTL has expired", func(t *testing.T) {
-			t.Parallel()
-			// --- ARRANGE ---
-			h := newTestHarness(t, 1*time.Hour) // Disable background cleanup to isolate dispatch logic.
-			item := h.newTestItem("req-expired-dispatch-evict", testFlow, testShortTTL)
-			mockQueue := h.addQueue(testFlow)
-			require.NoError(t, mockQueue.Add(item), "Adding item to mock queue should not fail")
-
-			// Have the policy select the item, but then advance time so it's expired by the time dispatchItem actually runs.
-			h.interFlowPolicySelectQueue = func(band framework.PriorityBandAccessor) (framework.FlowQueueAccessor, error) {
-				h.mockClock.Advance(testShortTTL * 2)
-				return mockQueue.FlowQueueAccessor(), nil
-			}
-
-			// --- ACT ---
-			h.Start()
-			defer h.Stop()
-			h.Go()
-
-			// The run loop will pick up the item and attempt dispatch, which will fail internally.
-			// We need a small sleep to allow the non-blocking run loop to process.
-			time.Sleep(50 * time.Millisecond)
-
-			// --- ASSERT ---
-			outcome, err := h.waitForFinalization(item)
-			assert.Equal(t, types.QueueOutcomeEvictedTTL, outcome, "The final outcome should be EvictedTTL")
-			require.Error(t, err, "An eviction at dispatch time should produce an error")
-			assert.ErrorIs(t, err, types.ErrTTLExpired, "The error should be of type ErrTTLExpired")
-		})
-
 		t.Run("should evict item on context cancellation", func(t *testing.T) {
 			t.Parallel()
 			// --- ARRANGE ---
 			h := newTestHarness(t, testCleanupTick)
 			ctx, cancel := context.WithCancel(context.Background())
 			req := typesmocks.NewMockFlowControlRequest(100, "req-ctx-cancel", testFlow, ctx)
-			item := NewItem(req, testTTL, h.mockClock.Now())
+			item := NewItem(req, testTTL, h.clock.Now())
 			h.addQueue(testFlow)
 
 			// --- ACT ---
 			h.Start()
-			defer h.Stop()
-			h.processor.Enqueue(item)
+			require.NoError(t, h.processor.Submit(item), "precondition: Submit should not fail")
 			h.Go()
-			cancel()                        // Cancel the context *after* the item is enqueued.
-			time.Sleep(testCleanupTick * 3) // Allow the cleanup goroutine time to run.
+			cancel() // Cancel the context after the item is enqueued.
+			// Manually invoke the cleanup logic to deterministically check for the cancelled context.
+			h.processor.cleanupExpired(h.clock.Now())
 
 			// --- ASSERT ---
 			outcome, err := h.waitForFinalization(item)
@@ -525,7 +444,7 @@ func TestShardProcessor(t *testing.T) {
 			outcome, err := h.waitForFinalization(item)
 			assert.Equal(t, types.QueueOutcomeEvictedOther, outcome, "The outcome should be EvictedOther")
 			require.Error(t, err, "An eviction on shutdown should produce an error")
-			assert.ErrorIs(t, err, types.ErrFlowControllerShutdown, "The error should be of type ErrFlowControllerShutdown")
+			assert.ErrorIs(t, err, types.ErrFlowControllerNotRunning, "The error should be of type ErrFlowControllerNotRunning")
 		})
 
 		t.Run("should handle concurrent enqueues and dispatch all items", func(t *testing.T) {
@@ -534,7 +453,7 @@ func TestShardProcessor(t *testing.T) {
 			h := newTestHarness(t, testCleanupTick)
 			const numConcurrentItems = 20
 			q := h.addQueue(testFlow)
-			itemsToTest := make([]*flowItem, 0, numConcurrentItems)
+			itemsToTest := make([]*FlowItem, 0, numConcurrentItems)
 			for i := 0; i < numConcurrentItems; i++ {
 				item := h.newTestItem(fmt.Sprintf("req-concurrent-%d", i), testFlow, testTTL)
 				itemsToTest = append(itemsToTest, item)
@@ -546,9 +465,9 @@ func TestShardProcessor(t *testing.T) {
 			var wg sync.WaitGroup
 			for _, item := range itemsToTest {
 				wg.Add(1)
-				go func(fi *flowItem) {
+				go func(fi *FlowItem) {
 					defer wg.Done()
-					h.processor.Enqueue(fi)
+					require.NoError(t, h.processor.Submit(fi), "Submit should not fail")
 				}(item)
 			}
 			h.Go()
@@ -597,8 +516,8 @@ func TestShardProcessor(t *testing.T) {
 			<-itemIsBeingDispatched
 
 			// 3. The dispatch goroutine is now paused. We can now safely win the "race" by running cleanup logic.
-			h.mockClock.Advance(testShortTTL * 2)
-			h.processor.cleanupExpired(h.mockClock.Now()) // This will remove and finalize the item.
+			h.clock.Step(testShortTTL * 2)
+			h.processor.cleanupExpired(h.clock.Now()) // This will remove and finalize the item.
 
 			// 5. Un-pause the dispatch goroutine. It will now fail to remove the item and the `dispatchCycle` will
 			//    correctly conclude without finalizing the item a second time.
@@ -647,7 +566,7 @@ func TestShardProcessor(t *testing.T) {
 			h.Start()
 			defer h.Stop()
 			h.Go()
-			h.processor.Enqueue(nil)
+			require.NoError(t, h.processor.Submit(nil), "Submit should not fail")
 
 			// --- ASSERT ---
 			// Allow a moment for the processor to potentially process the nil item.
@@ -666,32 +585,30 @@ func TestShardProcessor(t *testing.T) {
 			testCases := []struct {
 				name         string
 				setupHarness func(h *testHarness)
-				item         *flowItem
-				assert       func(t *testing.T, h *testHarness, item *flowItem)
+				item         *FlowItem
+				assert       func(t *testing.T, h *testHarness, item *FlowItem)
 			}{
 				{
 					name: "should reject item on registry queue lookup failure",
 					setupHarness: func(h *testHarness) {
 						h.ManagedQueueFunc = func(types.FlowKey) (contracts.ManagedQueue, error) { return nil, testErr }
 					},
-					assert: func(t *testing.T, h *testHarness, item *flowItem) {
-						outcome, err := item.FinalState()
-						assert.Equal(t, types.QueueOutcomeRejectedOther, outcome, "Outcome should be RejectedOther")
-						require.Error(t, err, "An error should be returned")
-						assert.ErrorIs(t, err, testErr, "The underlying error should be preserved")
+					assert: func(t *testing.T, h *testHarness, item *FlowItem) {
+						assert.Equal(t, types.QueueOutcomeRejectedOther, item.finalState.Outcome, "Outcome should be RejectedOther")
+						require.Error(t, item.finalState.Err, "An error should be returned")
+						assert.ErrorIs(t, item.finalState.Err, testErr, "The underlying error should be preserved")
 					},
 				},
 				{
 					name: "should reject item on registry priority band lookup failure",
 					setupHarness: func(h *testHarness) {
 						h.addQueue(testFlow)
-						h.PriorityBandAccessorFunc = func(uint) (framework.PriorityBandAccessor, error) { return nil, testErr }
+						h.PriorityBandAccessorFunc = func(int) (framework.PriorityBandAccessor, error) { return nil, testErr }
 					},
-					assert: func(t *testing.T, h *testHarness, item *flowItem) {
-						outcome, err := item.FinalState()
-						assert.Equal(t, types.QueueOutcomeRejectedOther, outcome, "Outcome should be RejectedOther")
-						require.Error(t, err, "An error should be returned")
-						assert.ErrorIs(t, err, testErr, "The underlying error should be preserved")
+					assert: func(t *testing.T, h *testHarness, item *FlowItem) {
+						assert.Equal(t, types.QueueOutcomeRejectedOther, item.finalState.Outcome, "Outcome should be RejectedOther")
+						require.Error(t, item.finalState.Err, "An error should be returned")
+						assert.ErrorIs(t, item.finalState.Err, testErr, "The underlying error should be preserved")
 					},
 				},
 				{
@@ -700,11 +617,10 @@ func TestShardProcessor(t *testing.T) {
 						mockQueue := h.addQueue(testFlow)
 						mockQueue.AddFunc = func(types.QueueItemAccessor) error { return testErr }
 					},
-					assert: func(t *testing.T, h *testHarness, item *flowItem) {
-						outcome, err := item.FinalState()
-						assert.Equal(t, types.QueueOutcomeRejectedOther, outcome, "Outcome should be RejectedOther")
-						require.Error(t, err, "An error should be returned")
-						assert.ErrorIs(t, err, testErr, "The underlying error should be preserved")
+					assert: func(t *testing.T, h *testHarness, item *FlowItem) {
+						assert.Equal(t, types.QueueOutcomeRejectedOther, item.finalState.Outcome, "Outcome should be RejectedOther")
+						require.Error(t, item.finalState.Err, "An error should be returned")
+						assert.ErrorIs(t, item.finalState.Err, testErr, "The underlying error should be preserved")
 					},
 				},
 				{
@@ -721,17 +637,16 @@ func TestShardProcessor(t *testing.T) {
 							assert.Equal(t, 0, addCallCount, "Queue.Add should not have been called for a finalized item")
 						})
 					},
-					item: func() *flowItem {
+					item: func() *FlowItem {
 						// Create a pre-finalized item.
 						item := newTestHarness(t, 0).newTestItem("req-finalized", testFlow, testTTL)
-						item.finalize(types.QueueOutcomeDispatched, nil)
+						item.Finalize(types.QueueOutcomeDispatched, nil)
 						return item
 					}(),
-					assert: func(t *testing.T, h *testHarness, item *flowItem) {
+					assert: func(t *testing.T, h *testHarness, item *FlowItem) {
 						// The item was already finalized, so its state should not change.
-						outcome, err := item.FinalState()
-						assert.Equal(t, types.QueueOutcomeDispatched, outcome, "Outcome should remain unchanged")
-						assert.NoError(t, err, "Error should remain unchanged")
+						assert.Equal(t, types.QueueOutcomeDispatched, item.finalState.Outcome, "Outcome should remain unchanged")
+						assert.NoError(t, item.finalState.Err, "Error should remain unchanged")
 					},
 				},
 			}
@@ -776,7 +691,7 @@ func TestShardProcessor(t *testing.T) {
 					itemByteSize: 1,
 					stats: contracts.ShardStats{
 						TotalCapacityBytes: 200, TotalByteSize: 100,
-						PerPriorityBandStats: map[uint]contracts.PriorityBandStats{
+						PerPriorityBandStats: map[int]contracts.PriorityBandStats{
 							testFlow.Priority: {ByteSize: 50, CapacityBytes: 50},
 						},
 					},
@@ -787,7 +702,7 @@ func TestShardProcessor(t *testing.T) {
 					itemByteSize: 1,
 					stats: contracts.ShardStats{
 						TotalCapacityBytes: 200, TotalByteSize: 100,
-						PerPriorityBandStats: map[uint]contracts.PriorityBandStats{}, // Missing stats for priority 10
+						PerPriorityBandStats: map[int]contracts.PriorityBandStats{}, // Missing stats for priority 10
 					},
 					expectHasCap: false,
 				},
@@ -796,7 +711,7 @@ func TestShardProcessor(t *testing.T) {
 					itemByteSize: 10,
 					stats: contracts.ShardStats{
 						TotalCapacityBytes: 200, TotalByteSize: 100,
-						PerPriorityBandStats: map[uint]contracts.PriorityBandStats{
+						PerPriorityBandStats: map[int]contracts.PriorityBandStats{
 							testFlow.Priority: {ByteSize: 50, CapacityBytes: 100},
 						},
 					},
@@ -836,17 +751,19 @@ func TestShardProcessor(t *testing.T) {
 						expectDidDispatch: false,
 					},
 					{
-						name: "should stop dispatching when filter signals pause",
+						name: "should block dispatch on HoL saturation",
 						setupHarness: func(h *testHarness) {
-							// Add an item that *could* be dispatched to prove the pause is effective.
-							q := h.addQueue(testFlow)
-							require.NoError(t, q.Add(h.newTestItem("item", testFlow, testTTL)))
-							h.processor.dispatchFilter = func(
-								_ context.Context,
-								_ framework.PriorityBandAccessor,
-								_ logr.Logger,
-							) (framework.PriorityBandAccessor, bool) {
-								return nil, true // Signal pause.
+							// Add a high-priority item that will be selected but is saturated.
+							qHigh := h.addQueue(testFlow) // priority 10
+							require.NoError(t, qHigh.Add(h.newTestItem("item-high", testFlow, testTTL)))
+
+							// Add a low-priority, viable item.
+							keyLow := types.FlowKey{ID: "flow-low", Priority: 5}
+							qLow := h.addQueue(keyLow)
+							require.NoError(t, qLow.Add(h.newTestItem("item-low", keyLow, testTTL)))
+
+							h.saturationDetector.IsSaturatedFunc = func(_ context.Context, _ []metrics.PodMetrics) bool {
+								return true
 							}
 						},
 						expectDidDispatch: false,
@@ -854,7 +771,7 @@ func TestShardProcessor(t *testing.T) {
 					{
 						name: "should skip band on priority band accessor error",
 						setupHarness: func(h *testHarness) {
-							h.PriorityBandAccessorFunc = func(uint) (framework.PriorityBandAccessor, error) {
+							h.PriorityBandAccessorFunc = func(int) (framework.PriorityBandAccessor, error) {
 								return nil, registryErr
 							}
 						},
@@ -955,62 +872,18 @@ func TestShardProcessor(t *testing.T) {
 				}
 			})
 
-			t.Run("should use filtered view of queues when filter is active", func(t *testing.T) {
-				t.Parallel()
-				// --- ARRANGE ---
-				h := newTestHarness(t, testCleanupTick)
-				flowB := types.FlowKey{ID: "flow-b", Priority: testFlow.Priority}
-				h.addQueue(testFlow)
-				qB := h.addQueue(flowB)
-				itemB := h.newTestItem("item-b", flowB, testTTL)
-				require.NoError(t, qB.Add(itemB))
-
-				// This filter only allows flow-b.
-				h.processor.dispatchFilter = func(
-					_ context.Context,
-					originalBand framework.PriorityBandAccessor,
-					_ logr.Logger,
-				) (framework.PriorityBandAccessor, bool) {
-					return newSubsetPriorityBandAccessor(originalBand, []types.FlowKey{flowB}), false
-				}
-
-				// This policy will be given the filtered view, so it should only see flow-b.
-				h.interFlowPolicySelectQueue = func(band framework.PriorityBandAccessor) (framework.FlowQueueAccessor, error) {
-					var flowIDs []string
-					band.IterateQueues(func(fqa framework.FlowQueueAccessor) bool {
-						flowIDs = append(flowIDs, fqa.FlowKey().ID)
-						return true
-					})
-					// This is the core assertion of the test.
-					require.ElementsMatch(t, []string{flowB.ID}, flowIDs, "Policy should only see the filtered flow")
-
-					// Select flow-b to prove the chain works.
-					q, _ := h.managedQueue(flowB)
-					return q.FlowQueueAccessor(), nil
-				}
-
-				// --- ACT ---
-				dispatched := h.processor.dispatchCycle(context.Background())
-
-				// --- ASSERT ---
-				assert.True(t, dispatched, "An item should have been dispatched from the filtered flow")
-				outcome, err := itemB.FinalState()
-				assert.Equal(t, types.QueueOutcomeDispatched, outcome, "The dispatched item's outcome should be correct")
-				assert.NoError(t, err, "The dispatched item should not have an error")
-			})
-
 			t.Run("should guarantee strict priority by starving lower priority items", func(t *testing.T) {
 				t.Parallel()
 				// --- ARRANGE ---
 				h := newTestHarness(t, testCleanupTick)
-				keyHigh := types.FlowKey{ID: "flow-high", Priority: 10}
-				keyLow := types.FlowKey{ID: "flow-low", Priority: 20}
+				keyHigh := types.FlowKey{ID: "flow-high", Priority: 20}
+				keyLow := types.FlowKey{ID: "flow-low", Priority: 10}
 				qHigh := h.addQueue(keyHigh)
 				qLow := h.addQueue(keyLow)
 
 				const numItems = 3
-				highPrioItems := make([]*flowItem, numItems)
-				lowPrioItems := make([]*flowItem, numItems)
+				highPrioItems := make([]*FlowItem, numItems)
+				lowPrioItems := make([]*FlowItem, numItems)
 				for i := range numItems {
 					// Add high priority items.
 					itemH := h.newTestItem(fmt.Sprintf("req-high-%d", i), keyHigh, testTTL)
@@ -1032,9 +905,9 @@ func TestShardProcessor(t *testing.T) {
 
 				// Verify all high-priority items are gone and low-priority items remain.
 				for _, item := range highPrioItems {
-					outcome, err := item.FinalState()
-					assert.Equal(t, types.QueueOutcomeDispatched, outcome, "High-priority item should be dispatched")
-					assert.NoError(t, err, "Dispatched high-priority item should not have an error")
+					assert.Equal(t, types.QueueOutcomeDispatched, item.finalState.Outcome,
+						"High-priority item should be dispatched")
+					assert.NoError(t, item.finalState.Err, "Dispatched high-priority item should not have an error")
 				}
 				assert.Equal(t, numItems, qLow.Len(), "Low-priority queue should still be full")
 
@@ -1109,7 +982,7 @@ func TestShardProcessor(t *testing.T) {
 				}
 
 				// --- ACT ---
-				h.mockClock.Advance(testShortTTL * 2) // Make the item expire.
+				h.clock.Step(testShortTTL * 2) // Make the item expire.
 				err := h.processor.dispatchItem(item, h.logger)
 
 				// --- ASSERT ---
@@ -1118,36 +991,11 @@ func TestShardProcessor(t *testing.T) {
 				assert.ErrorIs(t, err, types.ErrTTLExpired, "The error should be of type ErrTTLExpired")
 
 				// Second, check the final state of the item itself.
-				outcome, finalErr := item.FinalState()
-				assert.Equal(t, types.QueueOutcomeEvictedTTL, outcome, "The item's final outcome should be EvictedTTL")
-				require.Error(t, finalErr, "The item's final state should contain an error")
-				assert.ErrorIs(t, finalErr, types.ErrTTLExpired, "The item's final error should be of type ErrTTLExpired")
-			})
-
-			t.Run("should panic if queue returns item of wrong type", func(t *testing.T) {
-				t.Parallel()
-				// --- ARRANGE ---
-				h := newTestHarness(t, testCleanupTick)
-				badItem := &typesmocks.MockQueueItemAccessor{
-					OriginalRequestV: typesmocks.NewMockFlowControlRequest(0, "bad-item", testFlow, context.Background()),
-				}
-
-				h.ManagedQueueFunc = func(types.FlowKey) (contracts.ManagedQueue, error) {
-					return &mocks.MockManagedQueue{
-						RemoveFunc: func(types.QueueItemHandle) (types.QueueItemAccessor, error) {
-							return badItem, nil
-						},
-					}, nil
-				}
-
-				itemToDispatch := h.newTestItem("req-dispatch-panic", testFlow, testTTL)
-				expectedPanicMsg := fmt.Sprintf("%s: internal error: item %q of type %T is not a *flowItem",
-					errIntraFlow, "bad-item", badItem)
-
-				// --- ACT & ASSERT ---
-				assert.PanicsWithError(t, expectedPanicMsg, func() {
-					_ = h.processor.dispatchItem(itemToDispatch, h.logger)
-				}, "A type mismatch from a queue should cause a panic")
+				assert.Equal(t, types.QueueOutcomeEvictedTTL, item.finalState.Outcome,
+					"The item's final outcome should be EvictedTTL")
+				require.Error(t, item.finalState.Err, "The item's final state should contain an error")
+				assert.ErrorIs(t, item.finalState.Err, types.ErrTTLExpired,
+					"The item's final error should be of type ErrTTLExpired")
 			})
 		})
 
@@ -1162,16 +1010,15 @@ func TestShardProcessor(t *testing.T) {
 				item := h.newTestItem("req-expired", testFlow, 1*time.Millisecond)
 				q := h.addQueue(testFlow)
 				require.NoError(t, q.Add(item))
-				cleanupTime := h.mockClock.Now().Add(10 * time.Millisecond)
+				cleanupTime := h.clock.Now().Add(10 * time.Millisecond)
 
 				// --- ACT ---
 				h.processor.cleanupExpired(cleanupTime)
 
 				// --- ASSERT ---
-				outcome, err := item.FinalState()
-				assert.Equal(t, types.QueueOutcomeEvictedTTL, outcome, "Item outcome should be EvictedTTL")
-				require.Error(t, err, "Item should have an error")
-				assert.ErrorIs(t, err, types.ErrTTLExpired, "Item error should be ErrTTLExpired")
+				assert.Equal(t, types.QueueOutcomeEvictedTTL, item.finalState.Outcome, "Item outcome should be EvictedTTL")
+				require.Error(t, item.finalState.Err, "Item should have an error")
+				assert.ErrorIs(t, item.finalState.Err, types.ErrTTLExpired, "Item error should be ErrTTLExpired")
 			})
 
 			t.Run("should evict all items on shutdown", func(t *testing.T) {
@@ -1186,18 +1033,18 @@ func TestShardProcessor(t *testing.T) {
 				h.processor.evictAll()
 
 				// --- ASSERT ---
-				outcome, err := item.FinalState()
-				assert.Equal(t, types.QueueOutcomeEvictedOther, outcome, "Item outcome should be EvictedOther")
-				require.Error(t, err, "Item should have an error")
-				assert.ErrorIs(t, err, types.ErrFlowControllerShutdown, "Item error should be ErrFlowControllerShutdown")
+				assert.Equal(t, types.QueueOutcomeEvictedOther, item.finalState.Outcome, "Item outcome should be EvictedOther")
+				require.Error(t, item.finalState.Err, "Item should have an error")
+				assert.ErrorIs(t, item.finalState.Err, types.ErrFlowControllerNotRunning,
+					"Item error should be ErrFlowControllerNotRunning")
 			})
 
 			t.Run("should handle registry errors gracefully during concurrent processing", func(t *testing.T) {
 				t.Parallel()
 				// --- ARRANGE ---
 				h := newTestHarness(t, testCleanupTick)
-				h.AllOrderedPriorityLevelsFunc = func() []uint { return []uint{testFlow.Priority} }
-				h.PriorityBandAccessorFunc = func(p uint) (framework.PriorityBandAccessor, error) {
+				h.AllOrderedPriorityLevelsFunc = func() []int { return []int{testFlow.Priority} }
+				h.PriorityBandAccessorFunc = func(p int) (framework.PriorityBandAccessor, error) {
 					return nil, errors.New("registry error")
 				}
 
@@ -1257,6 +1104,105 @@ func TestShardProcessor(t *testing.T) {
 			})
 		})
 	})
+
+	t.Run("Public API", func(t *testing.T) {
+		t.Parallel()
+
+		t.Run("Submit", func(t *testing.T) {
+			t.Parallel()
+
+			t.Run("should return ErrProcessorBusy when channel is full", func(t *testing.T) {
+				t.Parallel()
+				h := newTestHarness(t, testCleanupTick)
+				h.processor.enqueueChan = make(chan *FlowItem, 1)
+				h.processor.enqueueChan <- h.newTestItem("item-filler", testFlow, testTTL) // Fill the channel to capacity.
+
+				// The next submit should be non-blocking and fail immediately.
+				err := h.processor.Submit(h.newTestItem("item-to-reject", testFlow, testTTL))
+				require.Error(t, err, "Submit must return an error when the channel is full")
+				assert.ErrorIs(t, err, ErrProcessorBusy, "The returned error must be ErrProcessorBusy")
+			})
+		})
+
+		t.Run("SubmitOrBlock", func(t *testing.T) {
+			t.Parallel()
+
+			t.Run("should block when channel is full and succeed when space becomes available", func(t *testing.T) {
+				t.Parallel()
+				h := newTestHarness(t, testCleanupTick)
+				h.processor.enqueueChan = make(chan *FlowItem, 1)
+				h.processor.enqueueChan <- h.newTestItem("item-filler", testFlow, testTTL) // Fill the channel to capacity.
+
+				itemToSubmit := h.newTestItem("item-to-block", testFlow, testTTL)
+				submitErr := make(chan error, 1)
+
+				// Run `SubmitOrBlock` in a separate goroutine, as it will block.
+				go func() {
+					submitErr <- h.processor.SubmitOrBlock(context.Background(), itemToSubmit)
+				}()
+
+				// Prove that the call is blocking by ensuring it hasn't returned an error yet.
+				time.Sleep(20 * time.Millisecond)
+				require.Len(t, submitErr, 0, "SubmitOrBlock should be blocking and not have returned yet")
+				<-h.processor.enqueueChan // Make space in the channel. This should unblock the goroutine.
+
+				select {
+				case err := <-submitErr:
+					require.NoError(t, err, "SubmitOrBlock should succeed and return no error after being unblocked")
+				case <-time.After(testWaitTimeout):
+					t.Fatal("SubmitOrBlock did not return after space was made in the channel")
+				}
+			})
+
+			t.Run("should unblock and return context error on cancellation", func(t *testing.T) {
+				t.Parallel()
+				h := newTestHarness(t, testCleanupTick)
+				h.processor.enqueueChan = make(chan *FlowItem) // Use an unbuffered channel to guarantee the first send blocks.
+				itemToSubmit := h.newTestItem("item-to-cancel", testFlow, testTTL)
+				submitErr := make(chan error, 1)
+				ctx, cancel := context.WithCancel(context.Background())
+
+				// Run `SubmitOrBlock` in a separate goroutine, as it will block.
+				go func() {
+					submitErr <- h.processor.SubmitOrBlock(ctx, itemToSubmit)
+				}()
+
+				// Prove that the call is blocking.
+				time.Sleep(20 * time.Millisecond)
+				require.Len(t, submitErr, 0, "SubmitOrBlock should be blocking and not have returned yet")
+				cancel() // Cancel the context. This should unblock the goroutine.
+
+				select {
+				case err := <-submitErr:
+					require.Error(t, err, "SubmitOrBlock should return an error after context cancellation")
+					assert.ErrorIs(t, err, context.Canceled, "The returned error must be context.Canceled")
+				case <-time.After(testWaitTimeout):
+					t.Fatal("SubmitOrBlock did not return after context was cancelled")
+				}
+			})
+
+			t.Run("should reject immediately if shutting down", func(t *testing.T) {
+				t.Parallel()
+				h := newTestHarness(t, testCleanupTick)
+				item := h.newTestItem("req-shutdown-reject", testFlow, testTTL)
+				h.addQueue(testFlow)
+
+				h.Start()
+				h.Go()
+				h.Stop() // Stop the processor, then immediately try to enqueue.
+				err := h.processor.SubmitOrBlock(context.Background(), item)
+
+				require.Error(t, err, "SubmitOrBlock should return an error when shutting down")
+				assert.ErrorIs(t, err, types.ErrFlowControllerNotRunning, "The error should be ErrFlowControllerNotRunning")
+
+				outcome, err := h.waitForFinalization(item)
+				assert.Equal(t, types.QueueOutcomeRejectedOther, outcome, "The outcome should be RejectedOther")
+				require.Error(t, err, "Finalization should include an error")
+				assert.ErrorIs(t, err, types.ErrFlowControllerNotRunning,
+					"The finalization error should be ErrFlowControllerNotRunning")
+			})
+		})
+	})
 }
 
 func TestCheckItemExpiry(t *testing.T) {
@@ -1326,7 +1272,7 @@ func TestCheckItemExpiry(t *testing.T) {
 					typesmocks.NewMockFlowControlRequest(100, "req-finalized", testFlow, context.Background()),
 					testTTL,
 					now)
-				i.finalize(types.QueueOutcomeDispatched, nil)
+				i.Finalize(types.QueueOutcomeDispatched, nil)
 				return i
 			}(),
 			now:           now,
@@ -1359,20 +1305,4 @@ func TestCheckItemExpiry(t *testing.T) {
 			}
 		})
 	}
-
-	t.Run("should panic on item of an unexpected type", func(t *testing.T) {
-		t.Parallel()
-		// --- ARRANGE ---
-		badItem := &typesmocks.MockQueueItemAccessor{
-			OriginalRequestV: typesmocks.NewMockFlowControlRequest(0, "item-bad-type", testFlow, context.Background()),
-		}
-
-		expectedPanicMsg := fmt.Sprintf("internal error: item %q of type %T is not a *flowItem",
-			badItem.OriginalRequestV.ID(), badItem)
-
-		// --- ACT & ASSERT ---
-		assert.PanicsWithError(t, expectedPanicMsg, func() {
-			_, _, _ = checkItemExpiry(badItem, time.Now())
-		}, "A type mismatch from a queue should cause a panic")
-	})
 }
diff --git a/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs/fcfs_test.go b/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs/fcfs_test.go
index 45c1442..cc6bcee 100644
--- a/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs/fcfs_test.go
+++ b/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs/fcfs_test.go
@@ -41,8 +41,7 @@ func TestFCFS_RequiredQueueCapabilities(t *testing.T) {
 	t.Parallel()
 	policy := newFCFS()
 	caps := policy.RequiredQueueCapabilities()
-	require.Len(t, caps, 1, "RequiredQueueCapabilities should return one capability")
-	assert.Equal(t, framework.CapabilityFIFO, caps[0], "Required capability should be FIFO")
+	require.Empty(t, caps, "No required capabilities should be returned")
 }
 
 func TestFCFS_SelectItem(t *testing.T) {
diff --git a/pkg/epp/flowcontrol/registry/config_test.go b/pkg/epp/flowcontrol/registry/config_test.go
index 0cf9f93..47814ae 100644
--- a/pkg/epp/flowcontrol/registry/config_test.go
+++ b/pkg/epp/flowcontrol/registry/config_test.go
@@ -18,7 +18,9 @@ package registry
 
 import (
 	"errors"
+	"fmt"
 	"testing"
+	"time"
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -27,7 +29,6 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/mocks"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/interflow/dispatch/besthead"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/interflow/dispatch/roundrobin"
 	intra "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/queue"
@@ -37,110 +38,138 @@ import (
 func TestConfig_ValidateAndApplyDefaults(t *testing.T) {
 	t.Parallel()
 
-	// Setup for failure injection tests
-	failingPolicyName := intra.RegisteredPolicyName("failing-policy-for-config-test")
-	intra.MustRegisterPolicy(failingPolicyName, func() (framework.IntraFlowDispatchPolicy, error) {
-		return nil, errors.New("policy instantiation failed")
-	})
-	failingQueueName := queue.RegisteredQueueName("failing-queue-for-config-test")
-	queue.MustRegisterQueue(failingQueueName, func(_ framework.ItemComparator) (framework.SafeQueue, error) {
-		return nil, errors.New("queue instantiation failed")
-	})
-
-	// Setup a mock policy with a specific capability requirement to test the compatibility check.
-	const mockCapability = framework.QueueCapability("TEST_CAPABILITY_FOR_CONFIG")
-	policyWithReqName := intra.RegisteredPolicyName("policy-with-req-for-config-test")
-	intra.MustRegisterPolicy(policyWithReqName, func() (framework.IntraFlowDispatchPolicy, error) {
-		return &mocks.MockIntraFlowDispatchPolicy{
-			NameV: string(policyWithReqName),
-			RequiredQueueCapabilitiesV: []framework.QueueCapability{
-				mockCapability,
-			},
-		}, nil
-	})
-
 	testCases := []struct {
 		name          string
-		input         *Config
+		input         Config
+		opts          []configOption
 		expectErr     bool
 		expectedErrIs error
-		expectedCfg   *Config
+		assertion     func(*testing.T, Config, *Config)
 	}{
+		// --- Success Paths ---
 		{
-			name: "Valid config with missing defaults",
-			input: &Config{
+			name: "ShouldApplyDefaults_WhenFieldsAreUnspecified",
+			input: Config{
 				PriorityBands: []PriorityBandConfig{
 					{Priority: 1, PriorityName: "High"},
-					{Priority: 2, PriorityName: "Low", InterFlowDispatchPolicy: roundrobin.RoundRobinPolicyName},
+					{Priority: 2, PriorityName: "Low", MaxBytes: 500},
 				},
 			},
-			expectErr: false,
-			expectedCfg: &Config{
-				PriorityBands: []PriorityBandConfig{
-					{
-						Priority:                1,
-						PriorityName:            "High",
-						IntraFlowDispatchPolicy: fcfs.FCFSPolicyName,
-						InterFlowDispatchPolicy: besthead.BestHeadPolicyName,
-						Queue:                   listqueue.ListQueueName,
-					},
-					{
-						Priority:                2,
-						PriorityName:            "Low",
-						IntraFlowDispatchPolicy: fcfs.FCFSPolicyName,
-						InterFlowDispatchPolicy: roundrobin.RoundRobinPolicyName,
-						Queue:                   listqueue.ListQueueName,
-					},
-				},
+			assertion: func(t *testing.T, _ Config, newCfg *Config) {
+				assert.Equal(t, defaultInitialShardCount, newCfg.InitialShardCount, "InitialShardCount should be defaulted")
+				assert.Equal(t, defaultFlowGCTimeout, newCfg.FlowGCTimeout, "FlowGCTimeout should be defaulted")
+				assert.Equal(t, defaultEventChannelBufferSize, newCfg.EventChannelBufferSize,
+					"EventChannelBufferSize should be defaulted")
+				require.Len(t, newCfg.PriorityBands, 2, "Should have two priority bands")
+				band1 := newCfg.PriorityBands[0]
+				assert.Equal(t, defaultIntraFlowDispatchPolicy, band1.IntraFlowDispatchPolicy,
+					"Band 1 IntraFlowDispatchPolicy should be defaulted")
+				assert.Equal(t, defaultInterFlowDispatchPolicy, band1.InterFlowDispatchPolicy,
+					"Band 1 InterFlowDispatchPolicy should be defaulted")
+				assert.Equal(t, defaultQueue, band1.Queue, "Band 1 Queue should be defaulted")
+				assert.Equal(t, defaultPriorityBandMaxBytes, band1.MaxBytes, "Band 1 MaxBytes should be defaulted")
+				band2 := newCfg.PriorityBands[1]
+				assert.Equal(t, uint64(500), band2.MaxBytes, "Band 2 MaxBytes should retain its specified value")
 			},
 		},
 		{
-			name: "Config with all fields specified and compatible",
-			input: &Config{
-				MaxBytes: 1000,
-				PriorityBands: []PriorityBandConfig{
-					{
-						Priority:                1,
-						PriorityName:            "High",
-						IntraFlowDispatchPolicy: fcfs.FCFSPolicyName, // Compatible with ListQueue
-						InterFlowDispatchPolicy: besthead.BestHeadPolicyName,
-						Queue:                   listqueue.ListQueueName,
-						MaxBytes:                500,
-					},
-				},
+			name: "ShouldRemainUnchanged_WhenConfigIsFullySpecifiedAndValid",
+			input: Config{
+				MaxBytes:               1000,
+				InitialShardCount:      10,
+				FlowGCTimeout:          10 * time.Minute,
+				EventChannelBufferSize: 5000,
+				PriorityBands: []PriorityBandConfig{{
+					Priority:                1,
+					PriorityName:            "Critical",
+					IntraFlowDispatchPolicy: fcfs.FCFSPolicyName,
+					InterFlowDispatchPolicy: besthead.BestHeadPolicyName,
+					Queue:                   listqueue.ListQueueName,
+					MaxBytes:                500,
+				}},
+			},
+			assertion: func(t *testing.T, originalCfg Config, newCfg *Config) {
+				assert.Equal(t, originalCfg.MaxBytes, newCfg.MaxBytes, "MaxBytes should remain unchanged")
+				assert.Equal(t, originalCfg.InitialShardCount, newCfg.InitialShardCount,
+					"InitialShardCount should remain unchanged")
+				assert.Equal(t, originalCfg.FlowGCTimeout, newCfg.FlowGCTimeout, "FlowGCTimeout should remain unchanged")
+				assert.Equal(t, originalCfg.EventChannelBufferSize, newCfg.EventChannelBufferSize,
+					"EventChannelBufferSize should remain unchanged")
+				assert.Equal(t, originalCfg.PriorityBands, newCfg.PriorityBands, "PriorityBands should remain unchanged")
+			},
+		},
+		{
+			name: "ShouldSucceed_WhenPolicyHasNoRequirements",
+			input: Config{
+				PriorityBands: []PriorityBandConfig{{
+					Priority:                1,
+					PriorityName:            "High",
+					IntraFlowDispatchPolicy: intra.RegisteredPolicyName("policy-without-req"),
+				}},
+			},
+			opts: []configOption{
+				withIntraFlowDispatchPolicyFactory(
+					func(_ intra.RegisteredPolicyName) (framework.IntraFlowDispatchPolicy, error) {
+						return &mocks.MockIntraFlowDispatchPolicy{
+							NameV:                      "policy-without-req",
+							RequiredQueueCapabilitiesV: []framework.QueueCapability{},
+						}, nil
+					}),
 			},
 			expectErr: false,
-			expectedCfg: &Config{ // Should be unchanged
-				MaxBytes: 1000,
-				PriorityBands: []PriorityBandConfig{
-					{
-						Priority:                1,
-						PriorityName:            "High",
-						IntraFlowDispatchPolicy: fcfs.FCFSPolicyName,
-						InterFlowDispatchPolicy: besthead.BestHeadPolicyName,
-						Queue:                   listqueue.ListQueueName,
-						MaxBytes:                500,
-					},
-				},
+		},
+		{
+			name: "ShouldSucceed_WhenPolicyAndQueueAreCompatible",
+			input: Config{
+				PriorityBands: []PriorityBandConfig{{
+					Priority:                1,
+					PriorityName:            "High",
+					IntraFlowDispatchPolicy: intra.RegisteredPolicyName("policy-with-reqs"),
+					Queue:                   queue.RegisteredQueueName("queue-with-reqs-capability"),
+				}},
+			},
+			opts: []configOption{
+				withIntraFlowDispatchPolicyFactory(
+					func(_ intra.RegisteredPolicyName) (framework.IntraFlowDispatchPolicy, error) {
+						return &mocks.MockIntraFlowDispatchPolicy{
+							RequiredQueueCapabilitiesV: []framework.QueueCapability{"capability-A", "capability-B"},
+						}, nil
+					}),
+				withQueueFactory(
+					func(_ queue.RegisteredQueueName, _ framework.ItemComparator) (framework.SafeQueue, error) {
+						return &mocks.MockSafeQueue{
+							CapabilitiesV: []framework.QueueCapability{"capability-A", "capability-B", "capability-C"},
+						}, nil
+					}),
+			},
+			expectErr: false,
+		},
+		// --- Core Behavioral Contracts ---
+		{
+			name: "ShouldReturnDeepCopy_AndNotMutateInput",
+			input: Config{
+				PriorityBands: []PriorityBandConfig{{Priority: 1, PriorityName: "High"}},
+			},
+			assertion: func(t *testing.T, originalCfg Config, newCfg *Config) {
+				newCfg.PriorityBands[0].PriorityName = "changed"
+				assert.NotEqual(t, originalCfg.PriorityBands[0].PriorityName, newCfg.PriorityBands[0].PriorityName,
+					"Original config should not be mutated by changes to the new config")
 			},
 		},
+		// --- Input Validation Errors ---
 		{
-			name:      "Error: No priority bands",
-			input:     &Config{PriorityBands: []PriorityBandConfig{}},
+			name:      "ShouldError_WhenNoPriorityBandsAreDefined",
+			input:     Config{PriorityBands: []PriorityBandConfig{}},
 			expectErr: true,
 		},
 		{
-			name: "Error: Missing PriorityName",
-			input: &Config{
-				PriorityBands: []PriorityBandConfig{
-					{Priority: 1},
-				},
-			},
+			name:      "ShouldError_WhenPriorityNameIsMissing",
+			input:     Config{PriorityBands: []PriorityBandConfig{{Priority: 1}}},
 			expectErr: true,
 		},
 		{
-			name: "Error: Duplicate priority level",
-			input: &Config{
+			name: "ShouldError_WhenPriorityLevelsAreDuplicated",
+			input: Config{
 				PriorityBands: []PriorityBandConfig{
 					{Priority: 1, PriorityName: "High"},
 					{Priority: 1, PriorityName: "Also High"},
@@ -149,62 +178,132 @@ func TestConfig_ValidateAndApplyDefaults(t *testing.T) {
 			expectErr: true,
 		},
 		{
-			name: "Error: Incompatible policy and queue",
-			input: &Config{
+			name: "ShouldError_WhenPriorityNamesAreDuplicated",
+			input: Config{
 				PriorityBands: []PriorityBandConfig{
-					{
-						Priority:                1,
-						PriorityName:            "High",
-						IntraFlowDispatchPolicy: policyWithReqName,       // Requires mock capability
-						Queue:                   listqueue.ListQueueName, // Does not provide it
-					},
+					{Priority: 1, PriorityName: "High"},
+					{Priority: 2, PriorityName: "High"},
 				},
 			},
+			expectErr: true,
+		},
+		// --- Plugin and Compatibility Errors ---
+		{
+			name: "ShouldError_WhenPolicyAndQueueAreIncompatible",
+			input: Config{
+				PriorityBands: []PriorityBandConfig{{
+					Priority:                1,
+					PriorityName:            "High",
+					IntraFlowDispatchPolicy: intra.RegisteredPolicyName("policy-with-req"),
+					Queue:                   listqueue.ListQueueName,
+				}},
+			},
+			opts: []configOption{withIntraFlowDispatchPolicyFactory(
+				func(_ intra.RegisteredPolicyName) (framework.IntraFlowDispatchPolicy, error) {
+					return &mocks.MockIntraFlowDispatchPolicy{
+						RequiredQueueCapabilitiesV: []framework.QueueCapability{framework.QueueCapability("required-capability")},
+					}, nil
+				})},
 			expectErr:     true,
 			expectedErrIs: contracts.ErrPolicyQueueIncompatible,
 		},
 		{
-			name: "Error: Failing policy instantiation",
-			input: &Config{
-				PriorityBands: []PriorityBandConfig{
-					{
-						Priority:                1,
-						PriorityName:            "High",
-						IntraFlowDispatchPolicy: failingPolicyName,
-						Queue:                   listqueue.ListQueueName,
-					},
-				},
+			name: "ShouldError_WhenQueueFactoryFails",
+			input: Config{
+				PriorityBands: []PriorityBandConfig{{
+					Priority:                1,
+					PriorityName:            "High",
+					Queue:                   queue.RegisteredQueueName("failing-queue"),
+					IntraFlowDispatchPolicy: intra.RegisteredPolicyName("policy-with-req"),
+				}},
 			},
 			expectErr: true,
+			opts: []configOption{
+				withIntraFlowDispatchPolicyFactory( // Forces queue instance creation for validating capabilities.
+					func(name intra.RegisteredPolicyName) (framework.IntraFlowDispatchPolicy, error) {
+						return &mocks.MockIntraFlowDispatchPolicy{
+							NameV:                      string(name),
+							RequiredQueueCapabilitiesV: []framework.QueueCapability{"required-capability"},
+						}, nil
+					},
+				),
+				withQueueFactory(func(_ queue.RegisteredQueueName, _ framework.ItemComparator) (framework.SafeQueue, error) {
+					return nil, errors.New("queue creation failed")
+				}),
+			},
 		},
 		{
-			name: "Error: Failing queue instantiation",
-			input: &Config{
-				PriorityBands: []PriorityBandConfig{
-					{
-						Priority:                1,
-						PriorityName:            "High",
-						IntraFlowDispatchPolicy: fcfs.FCFSPolicyName,
-						Queue:                   failingQueueName,
-					},
-				},
+			name: "ShouldError_WhenPolicyFactoryFails",
+			input: Config{
+				PriorityBands: []PriorityBandConfig{{
+					Priority:                1,
+					PriorityName:            "High",
+					IntraFlowDispatchPolicy: intra.RegisteredPolicyName("failing-policy"),
+				}},
 			},
+			opts: []configOption{withIntraFlowDispatchPolicyFactory(
+				func(_ intra.RegisteredPolicyName) (framework.IntraFlowDispatchPolicy, error) {
+					return nil, errors.New("policy creation failed")
+				})},
 			expectErr: true,
 		},
+		// --- Defaulting of Invalid Values ---
+		{
+			name: "ShouldApplyDefault_WhenInitialShardCountIsInvalid",
+			input: Config{
+				InitialShardCount: -1,
+				PriorityBands:     []PriorityBandConfig{{Priority: 1, PriorityName: "High"}},
+			},
+			assertion: func(t *testing.T, _ Config, newCfg *Config) {
+				assert.Equal(t, defaultInitialShardCount, newCfg.InitialShardCount,
+					"Invalid InitialShardCount should be corrected to the default")
+			},
+		},
+		{
+			name: "ShouldApplyDefault_WhenFlowGCTimeoutIsInvalid",
+			input: Config{
+				FlowGCTimeout: 0,
+				PriorityBands: []PriorityBandConfig{{Priority: 1, PriorityName: "High"}},
+			},
+			assertion: func(t *testing.T, _ Config, newCfg *Config) {
+				assert.Equal(t, defaultFlowGCTimeout, newCfg.FlowGCTimeout,
+					"Invalid FlowGCTimeout should be corrected to the default")
+			},
+		},
+		{
+			name: "ShouldApplyDefault_WhenEventChannelBufferSizeIsInvalid",
+			input: Config{
+				EventChannelBufferSize: -1,
+				PriorityBands:          []PriorityBandConfig{{Priority: 1, PriorityName: "High"}},
+			},
+			assertion: func(t *testing.T, _ Config, newCfg *Config) {
+				assert.Equal(t, defaultEventChannelBufferSize, newCfg.EventChannelBufferSize,
+					"Invalid EventChannelBufferSize should be corrected to the default")
+			},
+		},
 	}
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
 			t.Parallel()
-			err := tc.input.validateAndApplyDefaults()
+			originalInput := tc.input.deepCopy()
+			validatedCfg, err := newConfig(tc.input, tc.opts...)
+
 			if tc.expectErr {
-				require.Error(t, err, "Expected an error for this test case")
+				require.Error(t, err, "expected an error but got nil")
 				if tc.expectedErrIs != nil {
-					assert.ErrorIs(t, err, tc.expectedErrIs, "Error should be of the expected type")
+					assert.ErrorIs(t, err, tc.expectedErrIs, "error should wrap the expected error type")
 				}
+				assert.Nil(t, validatedCfg, "validatedCfg should be nil on error")
 			} else {
-				require.NoError(t, err, "Did not expect an error for this test case")
-				assert.Equal(t, tc.expectedCfg, tc.input, "Config after applying defaults does not match expected config")
+				require.NoError(t, err, "expected no error but got: %v", err)
+				require.NotNil(t, validatedCfg, "validatedCfg should not be nil on success")
+				if tc.assertion != nil {
+					tc.assertion(t, *originalInput, validatedCfg)
+				}
+
+				// Ensure the original config is not mutated.
+				assert.Equal(t, *originalInput, tc.input, "input config should not be mutated")
 			}
 		})
 	}
@@ -212,81 +311,201 @@ func TestConfig_ValidateAndApplyDefaults(t *testing.T) {
 
 func TestConfig_Partition(t *testing.T) {
 	t.Parallel()
-
-	baseConfig := &Config{
-		MaxBytes: 103,
+	baseCfg, err := newConfig(Config{
+		MaxBytes: 103, // Will not distribute evenly
 		PriorityBands: []PriorityBandConfig{
-			{Priority: 1, PriorityName: "High", MaxBytes: 55},
-			{Priority: 2, PriorityName: "Low", MaxBytes: 0}, // Should remain 0
+			{Priority: 1, PriorityName: "High", MaxBytes: 55}, // Will not distribute evenly
+			{Priority: 2, PriorityName: "Low", MaxBytes: 0},   // Will be defaulted to 1,000,000,000
+			{Priority: 3, PriorityName: "Mid", MaxBytes: 20},  // Will distribute evenly
 		},
-	}
+	})
+	require.NoError(t, err, "Test setup: creating the base config should not fail")
 
-	t.Run("EvenDistributionWithRemainder", func(t *testing.T) {
+	t.Run("ShouldDistributeWithRemainderCorrectly", func(t *testing.T) {
 		t.Parallel()
 		totalShards := 10
-		// Global: 103 / 10 = 10 remainder 3. First 3 shards get 11, rest get 10.
-		// Band 1: 55 / 10 = 5 remainder 5. First 5 shards get 6, rest get 5.
+		// Global: 103 / 10 = 10 rem 3. First 3 shards get 11, rest get 10.
+		// Band 1: 55 / 10 = 5 rem 5. First 5 shards get 6, rest get 5.
+		// Band 2 (defaulted): 1,000,000,000 / 10 = 100,000,000 for all shards.
+		// Band 3: 20 / 10 = 2 rem 0. All shards get 2.
 		expectedGlobalBytes := []uint64{11, 11, 11, 10, 10, 10, 10, 10, 10, 10}
 		expectedBand1Bytes := []uint64{6, 6, 6, 6, 6, 5, 5, 5, 5, 5}
 
-		var totalGlobal, totalBand1 uint64
+		var totalGlobal, totalBand1, totalBand2, totalBand3 uint64
 		for i := range totalShards {
-			partitioned, err := baseConfig.partition(i, totalShards)
-			require.NoError(t, err, "Partitioning should not fail for shard %d", i)
-			assert.Equal(t, expectedGlobalBytes[i], partitioned.MaxBytes, "Global MaxBytes for shard %d is incorrect", i)
-			require.Len(t, partitioned.PriorityBands, 2, "Partitioned config should have the same number of bands")
-			assert.Equal(t, expectedBand1Bytes[i], partitioned.PriorityBands[0].MaxBytes,
+			shardCfg := baseCfg.partition(i, totalShards)
+			require.NotNil(t, shardCfg, "Partitioned config for shard %d should not be nil", i)
+			assert.Equal(t, expectedGlobalBytes[i], shardCfg.MaxBytes, "Global MaxBytes for shard %d is incorrect", i)
+			require.Len(t, shardCfg.PriorityBands, 3, "Partitioned config should have 3 bands")
+			assert.Equal(t, expectedBand1Bytes[i], shardCfg.PriorityBands[0].MaxBytes,
 				"Band 1 MaxBytes for shard %d is incorrect", i)
-			assert.Zero(t, partitioned.PriorityBands[1].MaxBytes, "Band 2 MaxBytes should remain zero for shard %d", i)
-			totalGlobal += partitioned.MaxBytes
-			totalBand1 += partitioned.PriorityBands[0].MaxBytes
+
+			expectedBand2Bytes := defaultPriorityBandMaxBytes / uint64(totalShards)
+			assert.Equal(t, expectedBand2Bytes, shardCfg.PriorityBands[1].MaxBytes,
+				"Band 2 MaxBytes for shard %d is incorrect", i)
+			assert.Equal(t, uint64(2), shardCfg.PriorityBands[2].MaxBytes,
+				"Band 3 MaxBytes for shard %d is incorrect", i)
+
+			totalGlobal += shardCfg.MaxBytes
+			totalBand1 += shardCfg.PriorityBands[0].MaxBytes
+			totalBand2 += shardCfg.PriorityBands[1].MaxBytes
+			totalBand3 += shardCfg.PriorityBands[2].MaxBytes
 		}
-		assert.Equal(t, baseConfig.MaxBytes, totalGlobal, "Sum of partitioned global MaxBytes should equal original")
-		assert.Equal(t, baseConfig.PriorityBands[0].MaxBytes, totalBand1,
+		assert.Equal(t, baseCfg.MaxBytes, totalGlobal, "Sum of partitioned global MaxBytes should equal original")
+		assert.Equal(t, baseCfg.PriorityBands[0].MaxBytes, totalBand1,
 			"Sum of partitioned band 1 MaxBytes should equal original")
+		assert.Equal(t, defaultPriorityBandMaxBytes, totalBand2,
+			"Sum of partitioned band 2 MaxBytes should equal the default value")
+		assert.Equal(t, baseCfg.PriorityBands[2].MaxBytes, totalBand3,
+			"Sum of partitioned band 3 MaxBytes should equal original")
 	})
 
-	t.Run("SingleShard", func(t *testing.T) {
+	t.Run("ShouldHandleSingleShard", func(t *testing.T) {
 		t.Parallel()
-		partitioned, err := baseConfig.partition(0, 1)
-		require.NoError(t, err, "Partitioning for a single shard should not fail")
-		assert.Equal(t, baseConfig.MaxBytes, partitioned.MaxBytes, "Global MaxBytes should be unchanged for a single shard")
-		require.Len(t, partitioned.PriorityBands, 2, "Partitioned config should have the same number of bands")
-		assert.Equal(t, baseConfig.PriorityBands[0].MaxBytes, partitioned.PriorityBands[0].MaxBytes,
-			"Band 1 MaxBytes should be unchanged for a single shard")
+		shardCfg := baseCfg.partition(0, 1)
+		require.NotNil(t, shardCfg, "Partitioned config for single shard should not be nil")
+		assert.Equal(t, baseCfg.MaxBytes, shardCfg.MaxBytes, "Global MaxBytes should be unchanged for a single shard")
+		require.Len(t, shardCfg.PriorityBands, 3, "Partitioned config should have 3 bands")
+		assert.Equal(t, baseCfg.PriorityBands[0].MaxBytes, shardCfg.PriorityBands[0].MaxBytes,
+			"Band 1 MaxBytes should be unchanged")
 	})
 
-	t.Run("EmptyPriorityBands", func(t *testing.T) {
-		t.Parallel()
-		config := &Config{
-			MaxBytes:      100,
-			PriorityBands: []PriorityBandConfig{},
-		}
-		partitioned, err := config.partition(1, 3)
-		require.NoError(t, err, "Partitioning should not fail for empty priority bands")
-		assert.Equal(t, uint64(33), partitioned.MaxBytes, "Global MaxBytes should be partitioned correctly")
-		assert.Empty(t, partitioned.PriorityBands, "PriorityBands slice should be empty")
-		assert.NotNil(t, partitioned.PriorityBands, "PriorityBands slice should not be nil")
-	})
-
-	t.Run("ErrorHandling", func(t *testing.T) {
+	t.Run("ShouldPanic_WhenTotalShardsIsInvalid", func(t *testing.T) {
 		t.Parallel()
 		testCases := []struct {
 			name        string
-			shardIndex  int
 			totalShards int
 		}{
-			{"NegativeShardIndex", -1, 5},
-			{"ShardIndexOutOfBounds", 5, 5},
-			{"ZeroTotalShards", 0, 0},
-			{"NegativeTotalShards", 0, -1},
+			{"ZeroShards", 0},
+			{"NegativeShards", -1},
 		}
+
 		for _, tc := range testCases {
 			t.Run(tc.name, func(t *testing.T) {
 				t.Parallel()
-				_, err := baseConfig.partition(tc.shardIndex, tc.totalShards)
-				assert.Error(t, err, "Expected an error for invalid partitioning arguments")
+				assert.PanicsWithValue(t,
+					fmt.Sprintf("invariant violation: cannot partition into %d partitions", tc.totalShards),
+					func() { baseCfg.partition(0, tc.totalShards) },
+					"Should panic with a specific message when totalShards is not positive",
+				)
 			})
 		}
 	})
 }
+
+func TestConfig_GetBandConfig(t *testing.T) {
+	t.Parallel()
+	cfg, err := newConfig(Config{
+		PriorityBands: []PriorityBandConfig{
+			{Priority: 10, PriorityName: "High"},
+		},
+	})
+	require.NoError(t, err, "Test setup: creating the config should not fail")
+
+	t.Run("ShouldReturnCorrectConfig_ForExistingPriority", func(t *testing.T) {
+		t.Parallel()
+		bandCfg, err := cfg.getBandConfig(10)
+		require.NoError(t, err, "Should not error for an existing priority")
+		require.NotNil(t, bandCfg, "Returned band config should not be nil")
+		assert.Equal(t, "High", bandCfg.PriorityName, "Should return the correct band config")
+	})
+
+	t.Run("ShouldReturnError_ForNonExistentPriority", func(t *testing.T) {
+		t.Parallel()
+		_, err := cfg.getBandConfig(99)
+		assert.ErrorIs(t, err, contracts.ErrPriorityBandNotFound, "Error should wrap ErrPriorityBandNotFound")
+	})
+}
+
+func TestConfig_DeepCopy(t *testing.T) {
+	t.Parallel()
+
+	baseCfg := Config{
+		MaxBytes:               1000,
+		InitialShardCount:      5,
+		FlowGCTimeout:          10 * time.Minute,
+		EventChannelBufferSize: 2048,
+		PriorityBands: []PriorityBandConfig{
+			{Priority: 1, PriorityName: "A"},
+			{Priority: 2, PriorityName: "B"},
+		},
+	}
+	// Create a fully initialized "original" config to be the source of the copy.
+	original, err := newConfig(baseCfg)
+	require.NoError(t, err, "Setup for deep copy should not fail")
+
+	t.Run("ShouldReturnNil_ForNilReceiver", func(t *testing.T) {
+		t.Parallel()
+		var nilConfig *Config
+		assert.Nil(t, nilConfig.deepCopy(), "Deep copy of a nil config should be nil")
+	})
+
+	t.Run("ShouldCreateIdenticalButSeparateObject", func(t *testing.T) {
+		t.Parallel()
+		clone := original.deepCopy()
+
+		// Assert that the clone is not the same object in memory.
+		require.NotSame(t, original, clone, "Clone should be a new object in memory")
+		require.NotSame(t, &original.PriorityBands, &clone.PriorityBands, "PriorityBands slice should be a new object")
+		require.NotSame(t, &original.priorityBandMap, &clone.priorityBandMap, "priorityBandMap should be a new object")
+		assert.Equal(t, original.MaxBytes, clone.MaxBytes, "MaxBytes should be copied")
+		assert.Equal(t, original.InitialShardCount, clone.InitialShardCount, "InitialShardCount should be copied")
+		assert.Equal(t, original.FlowGCTimeout, clone.FlowGCTimeout, "FlowGCTimeout should be copied")
+		assert.Equal(t, original.EventChannelBufferSize, clone.EventChannelBufferSize,
+			"EventChannelBufferSize should be copied")
+		assert.Equal(t, original.PriorityBands, clone.PriorityBands, "PriorityBands should be deeply copied")
+	})
+
+	t.Run("ShouldBeIndependent_AfterCopying", func(t *testing.T) {
+		t.Parallel()
+		clone := original.deepCopy()
+
+		// Modify the clone
+		clone.MaxBytes = 2000
+		clone.PriorityBands[0].PriorityName = "modified"
+		// This modification through the map should also modify the slice element, as the map holds pointers.
+		clone.priorityBandMap[clone.PriorityBands[0].Priority].PriorityName = "modified-in-map"
+		clone.queueFactory = func(_ queue.RegisteredQueueName, _ framework.ItemComparator) (framework.SafeQueue, error) {
+			return nil, nil
+		}
+
+		// Assert that the original remains unchanged by comparing field by field for clarity.
+		assert.Equal(t, uint64(1000), original.MaxBytes, "Original MaxBytes should not be changed")
+		assert.Equal(t, 5, original.InitialShardCount, "Original InitialShardCount should not be changed")
+		assert.Equal(t, "A", original.PriorityBands[0].PriorityName, "Original PriorityBands slice should not be changed")
+		assert.Equal(t, "A", original.priorityBandMap[1].PriorityName, "Original priorityBandMap should not be changed")
+		assert.NotNil(t, original.queueFactory, "Original queueFactory should not be nil")
+
+		// Verify the change was contained to the clone. The final value should be the one set via the map.
+		assert.Equal(t, "modified-in-map", clone.PriorityBands[0].PriorityName,
+			"Clone's slice should reflect the change from the map")
+		assert.Equal(t, "modified-in-map", clone.priorityBandMap[1].PriorityName, "Clone's map should reflect the change")
+	})
+}
+
+func TestShardConfig_GetBandConfig(t *testing.T) {
+	t.Parallel()
+	baseCfg, err := newConfig(Config{
+		PriorityBands: []PriorityBandConfig{
+			{Priority: 10, PriorityName: "High"},
+			{Priority: 20, PriorityName: "Low"},
+		},
+	})
+	require.NoError(t, err, "Test setup: creating the base config should not fail")
+	shardCfg := baseCfg.partition(0, 2)
+	require.NotNil(t, shardCfg, "Test setup: partitioned config should not be nil")
+
+	t.Run("ShouldReturnCorrectConfig_ForExistingPriority", func(t *testing.T) {
+		t.Parallel()
+		bandCfg, err := shardCfg.getBandConfig(20)
+		require.NoError(t, err, "Should not error for an existing priority")
+		require.NotNil(t, bandCfg, "Returned band config should not be nil")
+		assert.Equal(t, "Low", bandCfg.PriorityName, "Should return the correct partitioned band config")
+	})
+
+	t.Run("ShouldReturnError_ForNonExistentPriority", func(t *testing.T) {
+		t.Parallel()
+		_, err := shardCfg.getBandConfig(99)
+		assert.ErrorIs(t, err, contracts.ErrPriorityBandNotFound, "Error should wrap ErrPriorityBandNotFound")
+	})
+}
diff --git a/pkg/epp/flowcontrol/registry/managedqueue_test.go b/pkg/epp/flowcontrol/registry/managedqueue_test.go
index ff73457..64e5ab8 100644
--- a/pkg/epp/flowcontrol/registry/managedqueue_test.go
+++ b/pkg/epp/flowcontrol/registry/managedqueue_test.go
@@ -26,6 +26,7 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
 	frameworkmocks "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/mocks"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/queue"
@@ -34,433 +35,477 @@ import (
 	typesmocks "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types/mocks"
 )
 
-var testFlowKey = types.FlowKey{ID: "test-flow", Priority: 1}
+// --- Test Harness and Mocks ---
 
-// testStatsReconciler is a mock implementation of the `parentStatsReconciler` function.
-// It captures the deltas it's called with, allowing tests to assert on them.
-type testStatsReconciler struct {
-	mu              sync.Mutex
-	lenDelta        int64
-	byteSizeDelta   int64
-	invocationCount int
+// mqTestHarness holds all components for testing a `managedQueue`.
+type mqTestHarness struct {
+	t          *testing.T
+	mq         *managedQueue
+	propagator *mockStatsPropagator
+	mockPolicy *frameworkmocks.MockIntraFlowDispatchPolicy
 }
 
-func (r *testStatsReconciler) reconcile(lenDelta, byteSizeDelta int64) {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	r.lenDelta += lenDelta
-	r.byteSizeDelta += byteSizeDelta
-	r.invocationCount++
-}
-
-func (r *testStatsReconciler) getStats() (lenDelta, byteSizeDelta int64, count int) {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	return r.lenDelta, r.byteSizeDelta, r.invocationCount
+// newMockedMqHarness creates a harness that uses a mocked underlying queue.
+// This is ideal for isolating and unit testing the decorator logic of `managedQueue`.
+func newMockedMqHarness(t *testing.T, queue *frameworkmocks.MockSafeQueue, key types.FlowKey) *mqTestHarness {
+	t.Helper()
+	return newMqHarness(t, queue, key, false)
 }
 
-// testFixture holds the components needed for a `managedQueue` test.
-type testFixture struct {
-	mq             *managedQueue
-	mockQueue      *frameworkmocks.MockSafeQueue
-	mockPolicy     *frameworkmocks.MockIntraFlowDispatchPolicy
-	reconciler     *testStatsReconciler
-	flowKey        types.FlowKey
-	mockComparator *frameworkmocks.MockItemComparator
+// newRealMqHarness creates a harness that uses a real "ListQueue" implementation.
+// This is essential for integration and concurrency tests.
+func newRealMqHarness(t *testing.T, key types.FlowKey) *mqTestHarness {
+	t.Helper()
+	q, err := queue.NewQueueFromName(listqueue.ListQueueName, nil)
+	require.NoError(t, err, "Test setup: creating a real ListQueue implementation should not fail")
+	return newMqHarness(t, q, key, false)
 }
 
-// setupTestManagedQueue creates a new test fixture for testing the `managedQueue`.
-func setupTestManagedQueue(t *testing.T) *testFixture {
+// newMqHarness is the base constructor for the test harness.
+func newMqHarness(t *testing.T, queue framework.SafeQueue, key types.FlowKey, isDraining bool) *mqTestHarness {
 	t.Helper()
 
-	mockQueue := &frameworkmocks.MockSafeQueue{}
-	reconciler := &testStatsReconciler{}
-	flowKey := types.FlowKey{ID: "test-flow", Priority: 1}
-	mockComparator := &frameworkmocks.MockItemComparator{}
+	propagator := &mockStatsPropagator{}
 	mockPolicy := &frameworkmocks.MockIntraFlowDispatchPolicy{
-		ComparatorV: mockComparator,
+		ComparatorV: &frameworkmocks.MockItemComparator{},
 	}
 
-	mq := newManagedQueue(
-		mockQueue,
-		mockPolicy,
-		flowKey,
-		logr.Discard(),
-		reconciler.reconcile,
-	)
-	require.NotNil(t, mq, "newManagedQueue should not return nil")
-
-	return &testFixture{
-		mq:             mq,
-		mockQueue:      mockQueue,
-		mockPolicy:     mockPolicy,
-		reconciler:     reconciler,
-		flowKey:        flowKey,
-		mockComparator: mockComparator,
+	isDrainingFunc := func() bool { return isDraining }
+	mq := newManagedQueue(queue, mockPolicy, key, logr.Discard(), propagator.propagate, isDrainingFunc)
+	require.NotNil(t, mq, "Test setup: newManagedQueue must return a valid instance")
+
+	return &mqTestHarness{
+		t:          t,
+		mq:         mq,
+		propagator: propagator,
+		mockPolicy: mockPolicy,
 	}
 }
 
-func TestManagedQueue_New(t *testing.T) {
-	t.Parallel()
-	f := setupTestManagedQueue(t)
+// setupWithItems pre-populates the queue and resets the mock propagator for focused testing.
+func (h *mqTestHarness) setupWithItems(items ...types.QueueItemAccessor) {
+	h.t.Helper()
+	for _, item := range items {
+		err := h.mq.Add(item)
+		require.NoError(h.t, err, "Harness setup: failed to add initial item to the queue")
+	}
+	h.propagator.reset()
+}
 
-	assert.Zero(t, f.mq.Len(), "A new managedQueue should have a length of 0")
-	assert.Zero(t, f.mq.ByteSize(), "A new managedQueue should have a byte size of 0")
+// mockStatsPropagator captures stat changes from the system under test.
+type mockStatsPropagator struct {
+	lenDelta      atomic.Int64
+	byteSizeDelta atomic.Int64
+}
+
+func (p *mockStatsPropagator) propagate(_ int, lenDelta, byteSizeDelta int64) {
+	p.lenDelta.Add(lenDelta)
+	p.byteSizeDelta.Add(byteSizeDelta)
+}
+
+func (p *mockStatsPropagator) reset() {
+	p.lenDelta.Store(0)
+	p.byteSizeDelta.Store(0)
+}
+
+// --- Unit Tests ---
+
+func TestManagedQueue_InitialState(t *testing.T) {
+	t.Parallel()
+	h := newMockedMqHarness(t, &frameworkmocks.MockSafeQueue{}, types.FlowKey{ID: "flow", Priority: 1})
+	assert.Zero(t, h.mq.Len(), "A newly initialized queue must have a length of 0")
+	assert.Zero(t, h.mq.ByteSize(), "A newly initialized queue must have a byte size of 0")
 }
 
 func TestManagedQueue_Add(t *testing.T) {
 	t.Parallel()
+	flowKey := types.FlowKey{ID: "flow", Priority: 1}
 
 	testCases := []struct {
 		name                  string
-		itemByteSize          uint64
-		mockAddError          error
-		expectError           bool
-		expectedLen           int
-		expectedByteSize      uint64
+		setupMock             func(q *frameworkmocks.MockSafeQueue)
+		isDraining            bool
+		expectErr             bool
+		expectErrIs           error // Optional
 		expectedLenDelta      int64
 		expectedByteSizeDelta int64
-		expectedReconcile     bool
 	}{
 		{
-			name:                  "Success",
-			itemByteSize:          100,
-			expectError:           false,
-			expectedLen:           1,
-			expectedByteSize:      100,
+			name: "ShouldSucceed_AndIncrementStats",
+			setupMock: func(q *frameworkmocks.MockSafeQueue) {
+				q.AddFunc = func(types.QueueItemAccessor) error { return nil }
+			},
+			isDraining:            false,
+			expectErr:             false,
 			expectedLenDelta:      1,
 			expectedByteSizeDelta: 100,
-			expectedReconcile:     true,
 		},
 		{
-			name:                  "Error from underlying queue",
-			itemByteSize:          100,
-			mockAddError:          errors.New("queue full"),
-			expectError:           true,
-			expectedLen:           0,
-			expectedByteSize:      0,
+			name: "ShouldFail_AndNotChangeStats_WhenUnderlyingQueueFails",
+			setupMock: func(q *frameworkmocks.MockSafeQueue) {
+				q.AddFunc = func(types.QueueItemAccessor) error { return errors.New("add failed") }
+			},
+			isDraining:            false,
+			expectErr:             true,
+			expectedLenDelta:      0,
+			expectedByteSizeDelta: 0,
+		},
+		{
+			name:                  "ShouldFail_AndNotChangeStats_WhenQueueIsDraining",
+			setupMock:             func(q *frameworkmocks.MockSafeQueue) {},
+			isDraining:            true,
+			expectErr:             true,
+			expectErrIs:           contracts.ErrShardDraining,
 			expectedLenDelta:      0,
 			expectedByteSizeDelta: 0,
-			expectedReconcile:     false,
 		},
 	}
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
 			t.Parallel()
-			f := setupTestManagedQueue(t)
-
-			// Configure mock
-			f.mockQueue.AddFunc = func(item types.QueueItemAccessor) error {
-				return tc.mockAddError
+			q := &frameworkmocks.MockSafeQueue{}
+			h := newMqHarness(t, q, flowKey, tc.isDraining)
+			item := typesmocks.NewMockQueueItemAccessor(100, "req", flowKey)
+			if tc.setupMock != nil {
+				tc.setupMock(q)
 			}
 
-			item := typesmocks.NewMockQueueItemAccessor(tc.itemByteSize, "req-1", testFlowKey)
-			err := f.mq.Add(item)
+			err := h.mq.Add(item)
 
-			if tc.expectError {
-				require.Error(t, err, "Add should have returned an error")
+			if tc.expectErr {
+				require.Error(t, err, "Add operation must fail when the underlying queue returns an error")
+				if tc.expectErrIs != nil {
+					assert.ErrorIs(t, err, tc.expectErrIs, "The returned error was not of the expected type")
+				}
 			} else {
-				require.NoError(t, err, "Add should not have returned an error")
+				require.NoError(t, err, "Add operation must succeed when the underlying queue accepts the item")
 			}
+			assert.Equal(t, tc.expectedLenDelta, h.propagator.lenDelta.Load(),
+				"The propagated length delta must exactly match the change in queue size")
+			assert.Equal(t, tc.expectedByteSizeDelta, h.propagator.byteSizeDelta.Load(),
+				"The propagated byte size delta must exactly match the change in queue size")
+		})
+	}
+}
 
-			// Assert final state
-			assert.Equal(t, tc.expectedLen, f.mq.Len(), "Final length should be as expected")
-			assert.Equal(t, tc.expectedByteSize, f.mq.ByteSize(), "Final byte size should be as expected")
+func TestManagedQueue_Remove(t *testing.T) {
+	t.Parallel()
+	flowKey := types.FlowKey{ID: "flow", Priority: 1}
 
-			// Assert reconciler state
-			lenDelta, byteSizeDelta, count := f.reconciler.getStats()
-			assert.Equal(t, tc.expectedLenDelta, lenDelta, "Reconciler length delta should be as expected")
-			assert.Equal(t, tc.expectedByteSizeDelta, byteSizeDelta, "Reconciler byte size delta should be as expected")
-			if tc.expectedReconcile {
-				assert.Equal(t, 1, count, "Reconciler should have been called once")
+	testCases := []struct {
+		name                  string
+		setupMock             func(q *frameworkmocks.MockSafeQueue, item types.QueueItemAccessor)
+		expectErr             bool
+		expectedLenDelta      int64
+		expectedByteSizeDelta int64
+	}{
+		{
+			name: "ShouldSucceed_AndDecrementStats",
+			setupMock: func(q *frameworkmocks.MockSafeQueue, item types.QueueItemAccessor) {
+				q.RemoveFunc = func(_ types.QueueItemHandle) (types.QueueItemAccessor, error) {
+					return item, nil
+				}
+			},
+			expectErr:             false,
+			expectedLenDelta:      -1,
+			expectedByteSizeDelta: -100,
+		},
+		{
+			name: "ShouldFail_AndNotChangeStats_WhenUnderlyingQueueFails",
+			setupMock: func(q *frameworkmocks.MockSafeQueue, item types.QueueItemAccessor) {
+				q.RemoveFunc = func(_ types.QueueItemHandle) (types.QueueItemAccessor, error) {
+					return nil, errors.New("remove failed")
+				}
+			},
+			expectErr:             true,
+			expectedLenDelta:      0,
+			expectedByteSizeDelta: 0,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
+			q := &frameworkmocks.MockSafeQueue{}
+			h := newMockedMqHarness(t, q, flowKey)
+			item := typesmocks.NewMockQueueItemAccessor(100, "req", flowKey)
+			h.setupWithItems(item)
+			tc.setupMock(q, item)
+
+			_, err := h.mq.Remove(item.Handle())
+
+			if tc.expectErr {
+				require.Error(t, err,
+					"Remove operation must fail when the underlying queue returns an error (e.g., item not found)")
 			} else {
-				assert.Zero(t, count, "Reconciler should not have been called")
+				require.NoError(t, err, "Remove operation must succeed when the underlying queue successfully removes the item")
 			}
+			assert.Equal(t, tc.expectedLenDelta, h.propagator.lenDelta.Load(),
+				"The propagated length delta must exactly match the change in queue size")
+			assert.Equal(t, tc.expectedByteSizeDelta, h.propagator.byteSizeDelta.Load(),
+				"The propagated byte size delta must exactly match the change in queue size")
 		})
 	}
 }
 
-func TestManagedQueue_Remove(t *testing.T) {
+func TestManagedQueue_Cleanup(t *testing.T) {
 	t.Parallel()
-	f := setupTestManagedQueue(t)
-
-	// Setup initial state
-	initialItem := typesmocks.NewMockQueueItemAccessor(100, "req-1", testFlowKey)
-	f.mockQueue.AddFunc = func(item types.QueueItemAccessor) error { return nil }
-	err := f.mq.Add(initialItem)
-	require.NoError(t, err, "Setup: Adding an item should not fail")
-	require.Equal(t, 1, f.mq.Len(), "Setup: Length should be 1 after adding an item")
-
-	// --- Test Success ---
-	t.Run("Success", func(t *testing.T) {
-		// Configure mock for Remove
-		f.mockQueue.RemoveFunc = func(handle types.QueueItemHandle) (types.QueueItemAccessor, error) {
-			return initialItem, nil
-		}
-
-		// Perform Remove
-		removedItem, err := f.mq.Remove(initialItem.Handle())
-		require.NoError(t, err, "Remove should not return an error")
-		assert.Equal(t, initialItem, removedItem, "Remove should return the correct item")
-
-		// Assert final state
-		assert.Zero(t, f.mq.Len(), "Length should be 0 after removing the only item")
-		assert.Zero(t, f.mq.ByteSize(), "ByteSize should be 0 after removing the only item")
-
-		// Assert reconciler state
-		lenDelta, byteSizeDelta, count := f.reconciler.getStats()
-		assert.Equal(t, int64(0), lenDelta, "Net length delta should be 0 after add and remove")
-		assert.Equal(t, int64(0), byteSizeDelta, "Net byte size delta should be 0 after add and remove")
-		assert.Equal(t, 2, count, "Reconciler should have been called for both Add and Remove")
-	})
-
-	// --- Test Error ---
-	t.Run("Error", func(t *testing.T) {
-		f := setupTestManagedQueue(t)
-		require.NoError(t, f.mq.Add(initialItem), "Setup: Adding an item should not fail")
+	flowKey := types.FlowKey{ID: "flow", Priority: 1}
 
-		// Configure mock to return an error
-		expectedErr := errors.New("item not found")
-		f.mockQueue.RemoveFunc = func(handle types.QueueItemHandle) (types.QueueItemAccessor, error) {
-			return nil, expectedErr
-		}
+	testCases := []struct {
+		name                  string
+		setupMock             func(q *frameworkmocks.MockSafeQueue, items []types.QueueItemAccessor)
+		expectErr             bool
+		expectedLenDelta      int64
+		expectedByteSizeDelta int64
+	}{
+		{
+			name: "ShouldSucceed_AndDecrementStats_WhenItemsRemoved",
+			setupMock: func(q *frameworkmocks.MockSafeQueue, items []types.QueueItemAccessor) {
+				q.CleanupFunc = func(_ framework.PredicateFunc) ([]types.QueueItemAccessor, error) {
+					return items, nil
+				}
+			},
+			expectErr:             false,
+			expectedLenDelta:      -2,
+			expectedByteSizeDelta: -125,
+		},
+		{
+			name: "ShouldSucceed_AndNotChangeStats_WhenNoItemsRemoved",
+			setupMock: func(q *frameworkmocks.MockSafeQueue, items []types.QueueItemAccessor) {
+				q.CleanupFunc = func(_ framework.PredicateFunc) ([]types.QueueItemAccessor, error) {
+					return nil, nil // Simulate no items matching predicate.
+				}
+			},
+			expectErr:             false,
+			expectedLenDelta:      0,
+			expectedByteSizeDelta: 0,
+		},
+		{
+			name: "ShouldFail_AndNotChangeStats_WhenUnderlyingQueueFails",
+			setupMock: func(q *frameworkmocks.MockSafeQueue, items []types.QueueItemAccessor) {
+				q.CleanupFunc = func(_ framework.PredicateFunc) ([]types.QueueItemAccessor, error) {
+					return nil, errors.New("cleanup failed")
+				}
+			},
+			expectErr:             true,
+			expectedLenDelta:      0,
+			expectedByteSizeDelta: 0,
+		},
+	}
 
-		_, err := f.mq.Remove(initialItem.Handle())
-		require.ErrorIs(t, err, expectedErr, "Remove should propagate the error")
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
+			q := &frameworkmocks.MockSafeQueue{}
+			h := newMockedMqHarness(t, q, flowKey)
+			items := []types.QueueItemAccessor{
+				typesmocks.NewMockQueueItemAccessor(50, "req", flowKey),
+				typesmocks.NewMockQueueItemAccessor(75, "req", flowKey),
+			}
+			h.setupWithItems(items...)
+			tc.setupMock(q, items)
 
-		// Assert state did not change
-		assert.Equal(t, 1, f.mq.Len(), "Length should not change on a failed remove")
-		assert.Equal(t, uint64(100), f.mq.ByteSize(), "ByteSize should not change on a failed remove")
+			_, err := h.mq.Cleanup(func(_ types.QueueItemAccessor) bool { return true })
 
-		// Assert reconciler was not called for the remove
-		_, _, count := f.reconciler.getStats()
-		assert.Equal(t, 1, count, "Reconciler should only have been called for the initial Add")
-	})
+			if tc.expectErr {
+				require.Error(t, err, "Cleanup operation must fail if the underlying queue implementation encounters an error")
+			} else {
+				require.NoError(t, err, "Cleanup operation must succeed if the underlying queue implementation succeeds")
+			}
+			assert.Equal(t, tc.expectedLenDelta, h.propagator.lenDelta.Load(),
+				"The propagated length delta must exactly match the total number of items removed during cleanup")
+			assert.Equal(t, tc.expectedByteSizeDelta, h.propagator.byteSizeDelta.Load(),
+				"The propagated byte size delta must exactly match the total size of items removed during cleanup")
+		})
+	}
 }
 
-func TestManagedQueue_CleanupAndDrain(t *testing.T) {
+func TestManagedQueue_Drain(t *testing.T) {
 	t.Parallel()
-	item1 := typesmocks.NewMockQueueItemAccessor(10, "req-1", testFlowKey)
-	item2 := typesmocks.NewMockQueueItemAccessor(20, "req-2", testFlowKey)
-	item3 := typesmocks.NewMockQueueItemAccessor(30, "req-3", testFlowKey)
+	flowKey := types.FlowKey{ID: "flow", Priority: 1}
 
-	// --- Test Cleanup ---
-	t.Run("Cleanup", func(t *testing.T) {
-		t.Parallel()
-		f := setupTestManagedQueue(t)
-		// Add initial items
-		require.NoError(t, f.mq.Add(item1), "Setup: Add item1 should not fail")
-		require.NoError(t, f.mq.Add(item2), "Setup: Add item2 should not fail")
-		require.NoError(t, f.mq.Add(item3), "Setup: Add item3 should not fail")
-		require.Equal(t, 3, f.mq.Len(), "Setup: Initial length should be 3")
-		require.Equal(t, uint64(60), f.mq.ByteSize(), "Setup: Initial byte size should be 60")
-
-		// Configure mock to clean up item2
-		f.mockQueue.CleanupFunc = func(p framework.PredicateFunc) ([]types.QueueItemAccessor, error) {
-			return []types.QueueItemAccessor{item2}, nil
-		}
-
-		cleaned, err := f.mq.Cleanup(func(i types.QueueItemAccessor) bool { return true })
-		require.NoError(t, err, "Cleanup should not return an error")
-		require.Len(t, cleaned, 1, "Cleanup should return one item")
-
-		// Assert final state
-		assert.Equal(t, 2, f.mq.Len(), "Length should be 2 after cleanup")
-		assert.Equal(t, uint64(40), f.mq.ByteSize(), "ByteSize should be 40 after cleanup")
-
-		// Assert reconciler state (3 adds, 1 cleanup)
-		lenDelta, byteSizeDelta, count := f.reconciler.getStats()
-		assert.Equal(t, int64(2), lenDelta, "Net length delta should be 2")
-		assert.Equal(t, int64(40), byteSizeDelta, "Net byte size delta should be 40")
-		assert.Equal(t, 4, count, "Reconciler should have been called 4 times")
-	})
+	testCases := []struct {
+		name                  string
+		setupMock             func(q *frameworkmocks.MockSafeQueue, items []types.QueueItemAccessor)
+		expectErr             bool
+		expectedLenDelta      int64
+		expectedByteSizeDelta int64
+	}{
+		{
+			name: "ShouldSucceed_AndDecrementStats",
+			setupMock: func(q *frameworkmocks.MockSafeQueue, items []types.QueueItemAccessor) {
+				q.DrainFunc = func() ([]types.QueueItemAccessor, error) {
+					return items, nil
+				}
+			},
+			expectErr:             false,
+			expectedLenDelta:      -2,
+			expectedByteSizeDelta: -125,
+		},
+		{
+			name: "ShouldFail_AndNotChangeStats_WhenUnderlyingQueueFails",
+			setupMock: func(q *frameworkmocks.MockSafeQueue, items []types.QueueItemAccessor) {
+				q.DrainFunc = func() ([]types.QueueItemAccessor, error) {
+					return nil, errors.New("drain failed")
+				}
+			},
+			expectErr:             true,
+			expectedLenDelta:      0,
+			expectedByteSizeDelta: 0,
+		},
+	}
 
-	// --- Test Drain ---
-	t.Run("Drain", func(t *testing.T) {
-		t.Parallel()
-		f := setupTestManagedQueue(t)
-		// Add initial items
-		require.NoError(t, f.mq.Add(item1), "Setup: Add item1 should not fail")
-		require.NoError(t, f.mq.Add(item2), "Setup: Add item2 should not fail")
-		require.Equal(t, 2, f.mq.Len(), "Setup: Initial length should be 2")
-		require.Equal(t, uint64(30), f.mq.ByteSize(), "Setup: Initial byte size should be 30")
-
-		// Configure mock to drain both items
-		f.mockQueue.DrainFunc = func() ([]types.QueueItemAccessor, error) {
-			return []types.QueueItemAccessor{item1, item2}, nil
-		}
-
-		drained, err := f.mq.Drain()
-		require.NoError(t, err, "Drain should not return an error")
-		require.Len(t, drained, 2, "Drain should return two items")
-
-		// Assert final state
-		assert.Zero(t, f.mq.Len(), "Length should be 0 after drain")
-		assert.Zero(t, f.mq.ByteSize(), "ByteSize should be 0 after drain")
-
-		// Assert reconciler state (2 adds, 1 drain)
-		lenDelta, byteSizeDelta, count := f.reconciler.getStats()
-		assert.Equal(t, int64(0), lenDelta, "Net length delta should be 0")
-		assert.Equal(t, int64(0), byteSizeDelta, "Net byte size delta should be 0")
-		assert.Equal(t, 3, count, "Reconciler should have been called 3 times")
-	})
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
+			q := &frameworkmocks.MockSafeQueue{}
+			h := newMockedMqHarness(t, q, flowKey)
+			items := []types.QueueItemAccessor{
+				typesmocks.NewMockQueueItemAccessor(50, "req", flowKey),
+				typesmocks.NewMockQueueItemAccessor(75, "req", flowKey),
+			}
+			h.setupWithItems(items...)
+			tc.setupMock(q, items)
 
-	// --- Test Error Paths ---
-	t.Run("ErrorPaths", func(t *testing.T) {
-		f := setupTestManagedQueue(t)
-		require.NoError(t, f.mq.Add(item1), "Setup: Adding an item should not fail")
-		initialLen, initialByteSize := f.mq.Len(), f.mq.ByteSize()
-
-		expectedErr := errors.New("internal error")
-
-		// Cleanup error
-		f.mockQueue.CleanupFunc = func(p framework.PredicateFunc) ([]types.QueueItemAccessor, error) {
-			return nil, expectedErr
-		}
-		_, err := f.mq.Cleanup(func(i types.QueueItemAccessor) bool { return true })
-		require.ErrorIs(t, err, expectedErr, "Cleanup should propagate error")
-		assert.Equal(t, initialLen, f.mq.Len(), "Len should not change on Cleanup error")
-		assert.Equal(t, initialByteSize, f.mq.ByteSize(), "ByteSize should not change on Cleanup error")
-
-		// Drain error
-		f.mockQueue.DrainFunc = func() ([]types.QueueItemAccessor, error) {
-			return nil, expectedErr
-		}
-		_, err = f.mq.Drain()
-		require.ErrorIs(t, err, expectedErr, "Drain should propagate error")
-		assert.Equal(t, initialLen, f.mq.Len(), "Len should not change on Drain error")
-		assert.Equal(t, initialByteSize, f.mq.ByteSize(), "ByteSize should not change on Drain error")
-	})
+			_, err := h.mq.Drain()
+
+			if tc.expectErr {
+				require.Error(t, err, "Drain operation must fail if the underlying queue implementation encounters an error")
+			} else {
+				require.NoError(t, err, "Drain operation must succeed if the underlying queue implementation succeeds")
+			}
+			assert.Equal(t, tc.expectedLenDelta, h.propagator.lenDelta.Load(),
+				"The propagated length delta must exactly match the total number of items drained")
+			assert.Equal(t, tc.expectedByteSizeDelta, h.propagator.byteSizeDelta.Load(),
+				"The propagated byte size delta must exactly match the total size of items drained")
+		})
+	}
 }
 
 func TestManagedQueue_FlowQueueAccessor(t *testing.T) {
 	t.Parallel()
-	f := setupTestManagedQueue(t)
-	item := typesmocks.NewMockQueueItemAccessor(100, "req-1", testFlowKey)
-
-	// Setup underlying queue state
-	f.mockQueue.PeekHeadV = item
-	f.mockQueue.PeekTailV = item
-	f.mockQueue.NameV = "MockQueue"
-	f.mockQueue.CapabilitiesV = []framework.QueueCapability{framework.CapabilityFIFO}
-
-	// Add an item to populate the managed queue's stats
-	require.NoError(t, f.mq.Add(item), "Setup: Adding an item should not fail")
-
-	// Get the accessor
-	accessor := f.mq.FlowQueueAccessor()
-	require.NotNil(t, accessor, "FlowQueueAccessor should not be nil")
-
-	// Assert that the accessor methods reflect the underlying state
-	assert.Equal(t, f.mq.Name(), accessor.Name(), "Accessor Name() should match managed queue")
-	assert.Equal(t, f.mq.Capabilities(), accessor.Capabilities(), "Accessor Capabilities() should match managed queue")
-	assert.Equal(t, f.mq.Len(), accessor.Len(), "Accessor Len() should match managed queue")
-	assert.Equal(t, f.mq.ByteSize(), accessor.ByteSize(), "Accessor ByteSize() should match managed queue")
-	assert.Equal(t, f.flowKey, accessor.FlowKey(), "Accessor FlowKey() should match managed queue")
-	assert.Equal(t, f.mockComparator, accessor.Comparator(), "Accessor Comparator() should match the one from the policy")
-	assert.Equal(t, f.mockComparator, f.mq.Comparator(), "ManagedQueue Comparator() should match the one from the policy")
-
-	peekedHead, err := accessor.PeekHead()
-	require.NoError(t, err, "Accessor PeekHead() should not return an error")
-	assert.Equal(t, item, peekedHead, "Accessor PeekHead() should return the correct item")
-
-	peekedTail, err := accessor.PeekTail()
-	require.NoError(t, err, "Accessor PeekTail() should not return an error")
-	assert.Equal(t, item, peekedTail, "Accessor PeekTail() should return the correct item")
-}
 
-func TestManagedQueue_Concurrency(t *testing.T) {
-	t.Parallel()
+	t.Run("ProxiesCalls", func(t *testing.T) {
+		t.Parallel()
+		flowKey := types.FlowKey{ID: "flow", Priority: 1}
+		q := &frameworkmocks.MockSafeQueue{}
+		harness := newMockedMqHarness(t, q, flowKey)
+		item := typesmocks.NewMockQueueItemAccessor(100, "req-1", flowKey)
+		q.PeekHeadV = item
+		q.PeekTailV = item
+		q.NameV = "MockQueue"
+		q.CapabilitiesV = []framework.QueueCapability{framework.CapabilityFIFO}
+		require.NoError(t, harness.mq.Add(item), "Test setup: Adding an item must succeed")
+
+		accessor := harness.mq.FlowQueueAccessor()
+		require.NotNil(t, accessor, "FlowQueueAccessor must return a non-nil instance (guaranteed by contract)")
+
+		assert.Equal(t, harness.mq.Name(), accessor.Name(), "Accessor Name() must proxy the underlying queue's name")
+		assert.Equal(t, harness.mq.Capabilities(), accessor.Capabilities(),
+			"Accessor Capabilities() must proxy the underlying queue's capabilities")
+		assert.Equal(t, harness.mq.Len(), accessor.Len(), "Accessor Len() must reflect the managed queue's current length")
+		assert.Equal(t, harness.mq.ByteSize(), accessor.ByteSize(),
+			"Accessor ByteSize() must reflect the managed queue's current byte size")
+		assert.Equal(t, flowKey, accessor.FlowKey(), "Accessor FlowKey() must return the correct identifier for the flow")
+		assert.Equal(t, harness.mockPolicy.Comparator(), accessor.Comparator(),
+			"Accessor Comparator() must return the comparator provided by the configured intra-flow policy")
+		assert.Equal(t, harness.mockPolicy.Comparator(), harness.mq.Comparator(),
+			"ManagedQueue Comparator() must also return the comparator provided by the configured intra-flow policy")
+
+		peekedHead, err := accessor.PeekHead()
+		require.NoError(t, err, "Accessor PeekHead() must succeed when the underlying queue succeeds")
+		assert.Same(t, item, peekedHead, "Accessor PeekHead() must return the exact item instance at the head")
+
+		peekedTail, err := accessor.PeekTail()
+		require.NoError(t, err, "Accessor PeekTail() must succeed when the underlying queue succeeds")
+		assert.Same(t, item, peekedTail, "Accessor PeekTail() must return the exact item instance at the tail")
+	})
 
-	// Use a real `listqueue` since it's concurrent-safe.
-	lq, err := queue.NewQueueFromName(listqueue.ListQueueName, nil)
-	require.NoError(t, err, "Setup: creating a real listqueue should not fail")
+	t.Run("EmptyQueue", func(t *testing.T) {
+		t.Parallel()
+		flowKey := types.FlowKey{ID: "flow", Priority: 1}
+		q := &frameworkmocks.MockSafeQueue{}
+		expectedErr := errors.New("queue is empty")
+		q.PeekHeadErrV = expectedErr
+		harness := newMockedMqHarness(t, q, flowKey)
+		accessor := harness.mq.FlowQueueAccessor()
+
+		_, err := accessor.PeekHead()
+		require.Error(t, err, "Accessor PeekHead() should return an error on an empty queue")
+		assert.ErrorIs(t, err, expectedErr, "Accessor should proxy the specific error from the underlying queue")
+	})
+}
 
-	reconciler := &testStatsReconciler{}
-	flowKey := types.FlowKey{ID: "conc-test-flow", Priority: 1}
-	mq := newManagedQueue(lq, nil, flowKey, logr.Discard(), reconciler.reconcile)
+// --- Concurrency Test ---
 
+// TestManagedQueue_Concurrency_StatsIntegrity validates that under high contention, the final propagated statistics
+// are consistent. It spins up multiple goroutines that concurrently and rapidly add and remove items to stress-test
+// the mutex protecting write operations and the atomic propagation of statistics.
+func TestManagedQueue_Concurrency_StatsIntegrity(t *testing.T) {
+	t.Parallel()
 	const (
-		numGoroutines   = 20
-		opsPerGoroutine = 200
-		itemByteSize    = 10
-		initialItems    = 500
+		numWorkers   = 10
+		opsPerWorker = 500
+		itemByteSize = 10
 	)
 
+	flowKey := types.FlowKey{ID: "flow", Priority: 1}
+	h := newRealMqHarness(t, flowKey)
 	var wg sync.WaitGroup
-	var successfulAdds, successfulRemoves atomic.Int64
-
-	// Use a channel as a concurrent-safe pool of handles for removal.
-	handles := make(chan types.QueueItemHandle, initialItems+(numGoroutines*opsPerGoroutine))
-
-	// Pre-fill the queue to give removers something to do immediately.
-	for range initialItems {
-		item := typesmocks.NewMockQueueItemAccessor(uint64(itemByteSize), "initial", testFlowKey)
-		require.NoError(t, mq.Add(item), "Setup: pre-filling queue should not fail")
-		handles <- item.Handle()
-	}
-	// Reset reconciler stats after setup so we only measure the concurrent phase.
-	*reconciler = testStatsReconciler{}
+	wg.Add(numWorkers)
 
-	// Launch goroutines to perform a mix of concurrent operations.
-	wg.Add(numGoroutines)
-	for i := range numGoroutines {
-		go func(routineID int) {
+	for range numWorkers {
+		go func() {
 			defer wg.Done()
-			for j := range opsPerGoroutine {
-				// Mix up operations between adding and removing.
-				if (routineID+j)%2 == 0 {
-					// Add operation
-					item := typesmocks.NewMockQueueItemAccessor(uint64(itemByteSize), "req", testFlowKey)
-					if err := mq.Add(item); err == nil {
-						successfulAdds.Add(1)
-						handles <- item.Handle()
-					}
-				} else {
-					// Remove operation
-					select {
-					case handle := <-handles:
-						if _, err := mq.Remove(handle); err == nil {
-							successfulRemoves.Add(1)
-						}
-					default:
-						// No handles available, do nothing. This can happen if removers are faster than adders.
-					}
-				}
+			for range opsPerWorker {
+				item := typesmocks.NewMockQueueItemAccessor(uint64(itemByteSize), "req", flowKey)
+				require.NoError(t, h.mq.Add(item), "Concurrent Add operation must succeed without errors or races")
+				// In this chaos test, `Remove` may fail if another goroutine removes the item first. This is expected.
+				_, _ = h.mq.Remove(item.Handle())
 			}
-		}(i)
+		}()
 	}
 	wg.Wait()
 
-	// All concurrent operations are complete. Drain any remaining items to get the final count.
-	drainedItems, err := mq.Drain()
-	require.NoError(t, err, "Draining the queue at the end should not fail")
-
-	// Final consistency checks.
-	finalItemCount := len(drainedItems)
-	finalByteSize := mq.ByteSize()
-
-	// The number of items left in the queue should match our tracking.
-	expectedFinalItemCount := initialItems + int(successfulAdds.Load()) - int(successfulRemoves.Load())
-	assert.Equal(t, expectedFinalItemCount, finalItemCount, "Final item count should match initial + adds - removes")
-
-	// The queue's internal stats must be zero after draining.
-	assert.Zero(t, mq.Len(), "Managed queue length must be zero after drain")
-	assert.Zero(t, finalByteSize, "Managed queue byte size must be zero after drain")
-
-	// The net change reported to the reconciler must match the net change from the concurrent phase,
-	// plus the final drain.
-	netLenChangeDuringConcurrentPhase := successfulAdds.Load() - successfulRemoves.Load()
-	netByteSizeChangeDuringConcurrentPhase := netLenChangeDuringConcurrentPhase * itemByteSize
-
-	lenDelta, byteSizeDelta, _ := reconciler.getStats()
+	// After all operations, the queue should ideally be empty, but we drain any remaining items to get a definitive final
+	// state.
+	_, err := h.mq.Drain()
+	require.NoError(t, err, "Final drain operation must succeed to finalize the test state")
+
+	assert.Zero(t, h.mq.Len(), "Final queue length must be zero after draining all remaining items")
+	assert.Zero(t, h.mq.ByteSize(), "Final queue byte size must be zero after draining all remaining items")
+	assert.Equal(t, int64(0), h.propagator.lenDelta.Load(),
+		"The net length delta propagated across all operations must be exactly zero")
+	assert.Equal(t, int64(0), h.propagator.byteSizeDelta.Load(),
+		"The net byte size delta propagated across all operations must be exactly zero")
+}
 
-	expectedLenDelta := netLenChangeDuringConcurrentPhase - int64(finalItemCount)
-	expectedByteSizeDelta := netByteSizeChangeDuringConcurrentPhase - int64(uint64(finalItemCount)*itemByteSize)
+// --- Invariant Test ---
 
-	assert.Equal(t, expectedLenDelta, lenDelta,
-		"Net length delta in reconciler should match the net change from all operations")
-	assert.Equal(t, expectedByteSizeDelta, byteSizeDelta,
-		"Net byte size delta in reconciler should match the net change from all operations")
+func TestManagedQueue_InvariantPanics_OnUnderflow(t *testing.T) {
+	t.Parallel()
+	flowKey := types.FlowKey{ID: "flow", Priority: 1}
+	item := typesmocks.NewMockQueueItemAccessor(100, "req", flowKey)
+	q := &frameworkmocks.MockSafeQueue{}
+	q.AddFunc = func(types.QueueItemAccessor) error { return nil }
+	q.RemoveFunc = func(types.QueueItemHandle) (types.QueueItemAccessor, error) {
+		return item, nil
+	}
+	h := newMockedMqHarness(t, q, flowKey)
+
+	require.NoError(t, h.mq.Add(item), "Test setup: Initial Add must succeed")
+	_, err := h.mq.Remove(item.Handle())
+	require.NoError(t, err, "Test setup: First Remove must succeed")
+
+	// This remove call should cause the stats to go negative.
+	assert.Panics(t,
+		func() {
+			// Mock the underlying queue to succeed on the second remove, even though it's logically inconsistent.
+			// This isolates the panic to the `managedQueue`'s decorator logic.
+			_, _ = h.mq.Remove(item.Handle())
+		},
+		"Attempting to remove an item that results in negative statistics must trigger an invariant violation panic",
+	)
 }
diff --git a/pkg/epp/flowcontrol/registry/registry_test.go b/pkg/epp/flowcontrol/registry/registry_test.go
new file mode 100644
index 0000000..b5bc322
--- /dev/null
+++ b/pkg/epp/flowcontrol/registry/registry_test.go
@@ -0,0 +1,645 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package registry
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/go-logr/logr"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	testclock "k8s.io/utils/clock/testing"
+
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
+	inter "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/interflow/dispatch"
+	intra "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types/mocks"
+)
+
+// --- Test Harness ---
+
+// registryTestHarness provides a fully initialized test harness for the `FlowRegistry`.
+type registryTestHarness struct {
+	t         *testing.T
+	fr        *FlowRegistry
+	config    Config
+	fakeClock *testclock.FakeClock
+}
+
+// harnessOptions configures the test harness.
+type harnessOptions struct {
+	config            *Config
+	initialShardCount int
+}
+
+// newRegistryTestHarness creates and starts a new `FlowRegistry` for testing.
+func newRegistryTestHarness(t *testing.T, opts harnessOptions) *registryTestHarness {
+	t.Helper()
+
+	var config Config
+	if opts.config != nil {
+		config = *opts.config
+	} else {
+		config = Config{
+			FlowGCTimeout: 5 * time.Minute, // Use a realistic but controllable GC time.
+			PriorityBands: []PriorityBandConfig{
+				{Priority: highPriority, PriorityName: "High"},
+				{Priority: lowPriority, PriorityName: "Low"},
+			},
+		}
+	}
+	if opts.initialShardCount > 0 {
+		config.InitialShardCount = opts.initialShardCount
+	}
+
+	validatedCfg, err := config.ValidateAndApplyDefaults()
+	require.NoError(t, err, "Test setup: validating config should not fail")
+
+	fakeClock := testclock.NewFakeClock(time.Now())
+	registryOpts := []RegistryOption{withClock(fakeClock)}
+	fr, err := NewFlowRegistry(*validatedCfg, logr.Discard(), registryOpts...)
+	require.NoError(t, err, "Test setup: NewFlowRegistry should not fail")
+
+	// Start the GC loop in the background.
+	ctx, cancel := context.WithCancel(context.Background())
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		fr.Run(ctx)
+	}()
+	t.Cleanup(func() {
+		cancel()
+		wg.Wait()
+	})
+
+	return &registryTestHarness{
+		t:         t,
+		fr:        fr,
+		config:    *fr.config,
+		fakeClock: fakeClock,
+	}
+}
+
+// assertFlowExists synchronously checks if a flow's queue exists on the first shard.
+func (h *registryTestHarness) assertFlowExists(key types.FlowKey, msgAndArgs ...any) {
+	h.t.Helper()
+	require.NotEmpty(h.t, h.fr.allShards, "Cannot check for flow existence when no shards are present")
+	_, err := h.fr.allShards[0].ManagedQueue(key)
+	assert.NoError(h.t, err, msgAndArgs...)
+}
+
+// assertFlowDoesNotExist synchronously checks if a flow's queue does not exist.
+func (h *registryTestHarness) assertFlowDoesNotExist(key types.FlowKey, msgAndArgs ...any) {
+	h.t.Helper()
+	if len(h.fr.allShards) == 0 {
+		assert.True(h.t, true, "Flow correctly does not exist because no shards exist")
+		return
+	}
+	_, err := h.fr.allShards[0].ManagedQueue(key)
+	require.Error(h.t, err, "Expected an error when getting a non-existent flow, but got none")
+	assert.ErrorIs(h.t, err, contracts.ErrFlowInstanceNotFound, msgAndArgs...)
+}
+
+// openConnectionOnFlow ensures a flow is registered for the provided `key`.
+func (h *registryTestHarness) openConnectionOnFlow(key types.FlowKey) {
+	h.t.Helper()
+	err := h.fr.WithConnection(key, func(conn contracts.ActiveFlowConnection) error { return nil })
+	require.NoError(h.t, err, "Registering flow %s should not fail", key)
+	h.assertFlowExists(key, "Flow %s should exist after registration", key)
+}
+
+// --- Constructor and Lifecycle Tests ---
+
+func TestFlowRegistry_New(t *testing.T) {
+	t.Parallel()
+
+	t.Run("ShouldFail_WhenInitialShardCreationFails", func(t *testing.T) {
+		t.Parallel()
+		config, err := newConfig(
+			Config{PriorityBands: []PriorityBandConfig{{Priority: highPriority, PriorityName: "A"}}},
+			withInterFlowDispatchPolicyFactory(func(inter.RegisteredPolicyName) (framework.InterFlowDispatchPolicy, error) {
+				return nil, errors.New("injected factory failure")
+			}),
+		)
+		require.NoError(t, err, "Test setup: creating the config object itself should not fail")
+		_, err = NewFlowRegistry(*config, logr.Discard())
+		require.Error(t, err, "NewFlowRegistry should fail when initial shard setup fails")
+		assert.Contains(t, err.Error(), "injected factory failure",
+			"Error message should reflect the root cause from the failing plugin factory")
+	})
+}
+
+// --- `FlowRegistryClient` API Tests ---
+
+func TestFlowRegistry_WithConnection_AndHandle(t *testing.T) {
+	t.Parallel()
+
+	t.Run("ShouldJITRegisterFlow_OnFirstConnection", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{})
+		key := types.FlowKey{ID: "jit-flow", Priority: highPriority}
+
+		h.assertFlowDoesNotExist(key, "Flow should not exist before the first connection")
+
+		err := h.fr.WithConnection(key, func(conn contracts.ActiveFlowConnection) error {
+			h.assertFlowExists(key, "Flow should exist immediately after JIT registration within the connection")
+			require.NotNil(t, conn, "Connection handle provided to callback must not be nil")
+			return nil
+		})
+
+		require.NoError(t, err, "WithConnection should succeed for a new flow")
+		h.assertFlowExists(key, "Flow should remain in the registry after the connection is closed")
+	})
+
+	t.Run("ShouldFail_WhenFlowIDIsEmpty", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{})
+		key := types.FlowKey{ID: "", Priority: highPriority} // Invalid key
+
+		err := h.fr.WithConnection(key, func(conn contracts.ActiveFlowConnection) error {
+			t.Fatal("Callback must not be executed when the provided flow key is invalid")
+			return nil
+		})
+
+		require.Error(t, err, "WithConnection must return an error for an empty flow ID")
+		assert.ErrorIs(t, err, contracts.ErrFlowIDEmpty, "The returned error must be of the correct type")
+	})
+
+	t.Run("ShouldFail_WhenJITFails", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{})
+		h.fr.config.intraFlowDispatchPolicyFactory = func(intra.RegisteredPolicyName) (framework.IntraFlowDispatchPolicy, error) {
+			return nil, errors.New("injected factory failure")
+		}
+		key := types.FlowKey{ID: "test-flow", Priority: highPriority}
+
+		err := h.fr.WithConnection(key, func(conn contracts.ActiveFlowConnection) error {
+			t.Fatal("Callback must not be executed when the flow failes to register JIT")
+			return nil
+		})
+
+		require.Error(t, err, "WithConnection must return an error for a failed flow JIT registration")
+		assert.ErrorContains(t, err, "injected factory failure", "The returned error must propagate the reason")
+	})
+
+	t.Run("Handle_Shards_ShouldReturnAllActiveShardsAndBeACopy", func(t *testing.T) {
+		t.Parallel()
+		// Create a registry with a known mixed topology of Active and Draining shards.
+		h := newRegistryTestHarness(t, harnessOptions{initialShardCount: 3})
+		err := h.fr.updateShardCount(2) // This leaves one shard in the Draining state.
+		require.NoError(t, err, "Test setup: scaling down to create a draining shard should not fail")
+		require.Len(t, h.fr.allShards, 3, "Test setup: should have 2 active and 1 draining shard")
+
+		key := types.FlowKey{ID: "test-flow", Priority: highPriority}
+
+		err = h.fr.WithConnection(key, func(conn contracts.ActiveFlowConnection) error {
+			shards := conn.ActiveShards()
+
+			assert.Len(t, shards, 2, "ActiveShards() must only return the Active shards")
+
+			// Assert it's a copy by maliciously modifying it.
+			require.NotEmpty(t, shards, "Test setup assumes shards are present")
+			shards[0] = nil // Modify the local copy.
+
+			return nil
+		})
+		require.NoError(t, err)
+
+		// Prove the registry's internal state was not mutated by the modification.
+		assert.NotNil(t, h.fr.activeShards[0],
+			"Modifying the slice returned by ActiveShards() must not affect the registry's internal state")
+	})
+}
+
+// --- `FlowRegistryAdmin` API Tests ---
+
+func TestFlowRegistry_Stats(t *testing.T) {
+	t.Parallel()
+
+	h := newRegistryTestHarness(t, harnessOptions{initialShardCount: 2})
+	keyHigh := types.FlowKey{ID: "high-pri-flow", Priority: highPriority}
+	keyLow := types.FlowKey{ID: "low-pri-flow", Priority: lowPriority}
+	h.openConnectionOnFlow(keyHigh)
+	h.openConnectionOnFlow(keyLow)
+
+	shards := h.fr.allShards
+	require.Len(t, shards, 2, "Test setup assumes 2 shards")
+	mqHigh0, _ := shards[0].ManagedQueue(keyHigh)
+	mqHigh1, _ := shards[1].ManagedQueue(keyHigh)
+	mqLow1, _ := shards[1].ManagedQueue(keyLow)
+	require.NoError(t, mqHigh0.Add(mocks.NewMockQueueItemAccessor(10, "req1", keyHigh)),
+		"Adding item to queue should not fail")
+	require.NoError(t, mqHigh1.Add(mocks.NewMockQueueItemAccessor(20, "req2", keyHigh)),
+		"Adding item to queue should not fail")
+	require.NoError(t, mqLow1.Add(mocks.NewMockQueueItemAccessor(30, "req3", keyLow)),
+		"Adding item to queue should not fail")
+
+	// Although the production `Stats()` method provides a 'fuzzy snapshot' under high contention, our test validates it
+	// in a quiescent state, so these assertions can and must be exact.
+	globalStats := h.fr.Stats()
+	assert.Equal(t, uint64(3), globalStats.TotalLen, "Global TotalLen should be the sum of all items")
+	assert.Equal(t, uint64(60), globalStats.TotalByteSize, "Global TotalByteSize should be the sum of all item sizes")
+
+	shardStats := h.fr.ShardStats()
+	require.Len(t, shardStats, 2, "Should return stats for 2 shards")
+	var totalShardLen, totalShardBytes uint64
+	for _, ss := range shardStats {
+		assert.True(t, ss.IsActive, "All shards should be active in this test")
+		assert.NotEmpty(t, ss.PerPriorityBandStats, "Each shard should have stats for its priority bands")
+		assert.NotEmpty(t, ss.ID, "Each shard should have a non-empty ID")
+		totalShardLen += ss.TotalLen
+		totalShardBytes += ss.TotalByteSize
+	}
+	assert.Equal(t, globalStats.TotalLen, totalShardLen, "Sum of shard lengths must equal global length")
+	assert.Equal(t, globalStats.TotalByteSize, totalShardBytes, "Sum of shard byte sizes must equal global byte size")
+}
+
+// --- Garbage Collection Tests ---
+
+func TestFlowRegistry_GarbageCollection(t *testing.T) {
+	t.Run("ShouldCollectIdleFlow", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{})
+		key := types.FlowKey{ID: "idle-flow", Priority: highPriority}
+
+		h.openConnectionOnFlow(key)                            // Create a flow, which is born Idle.
+		h.fakeClock.Step(h.config.FlowGCTimeout + time.Second) // Advance the clock just past the GC timeout.
+		h.fr.executeGCCycle()                                  // Manually and deterministically trigger a GC cycle.
+
+		h.assertFlowDoesNotExist(key, "Idle flow should be collected by the GC")
+	})
+
+	t.Run("ShouldNotCollectActiveFlow", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{})
+		key := types.FlowKey{ID: "active-flow", Priority: highPriority}
+
+		var wg sync.WaitGroup
+		leaseAcquired := make(chan struct{})
+		releaseLease := make(chan struct{})
+		wg.Add(1)
+
+		go func() {
+			// This goroutine holds the lease. It will not exit until the main test goroutine calls `wg.Done()`.
+			defer wg.Done()
+			err := h.fr.WithConnection(key, func(contracts.ActiveFlowConnection) error {
+				close(leaseAcquired) // Signal to the main test that the lease is now active.
+				<-releaseLease       // Block here, holding the lease, until signaled.
+
+				return nil
+			})
+			require.NoError(t, err, "WithConnection in the background goroutine should not fail")
+		}()
+		t.Cleanup(func() {
+			close(releaseLease) // Unblock the goroutine.
+			wg.Wait()           // Wait for the goroutine to fully exit.
+		})
+
+		<-leaseAcquired                              // Wait until the goroutine confirms that it has acquired the lease.
+		h.fakeClock.Step(h.config.FlowGCTimeout * 2) // Advance the clock well past the GC timeout.
+		h.fr.executeGCCycle()                        // Manually and deterministically trigger a GC cycle.
+
+		h.assertFlowExists(key, "An active flow must not be garbage collected, even after a forced GC cycle")
+	})
+
+	t.Run("ShouldResetGCTimer_WhenFlowBecomesActive", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{})
+		key := types.FlowKey{ID: "reactivated-flow", Priority: highPriority}
+		h.openConnectionOnFlow(key)                            // Create an flow with a new idleness timer.
+		h.fakeClock.Step(h.config.FlowGCTimeout - time.Second) // Advance the clock to just before the GC timeout.
+		h.openConnectionOnFlow(key)                            // Open a new connection, resetting its idleness timer.
+		h.fakeClock.Step(2 * time.Second)                      // Advance the clock again.
+		h.fr.executeGCCycle()                                  // Manually and deterministically trigger a GC cycle.
+
+		h.assertFlowExists(key, "Flow should survive GC because its idleness timer was reset")
+	})
+
+	t.Run("ShouldAbortSweep_WhenFlowBecomesActiveAfterScan", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{})
+		key := types.FlowKey{ID: "re-activated-flow", Priority: highPriority}
+		h.openConnectionOnFlow(key)
+
+		// Make the flow a candidate for GC.
+		h.fakeClock.Step(h.config.FlowGCTimeout + time.Second)
+		candidates := []types.FlowKey{key}
+
+		// Get the flow's state so we can manipulate its lock.
+		val, ok := h.fr.flowStates.Load(key)
+		require.True(t, ok, "Test setup: flow state must exist")
+		state := val.(*flowState)
+
+		// Lock the flow's `gcLock` to pause the GC.
+		state.gcLock.Lock()
+		defer state.gcLock.Unlock()
+
+		// Start the sweep in the background; it will block.
+		sweepDone := make(chan struct{})
+		go func() {
+			defer close(sweepDone)
+			h.fr.verifyAndSweepFlows(candidates)
+		}()
+
+		// While the sweep is blocked, make the flow Active again.
+		// This simulates a new connection arriving just in time.
+		state.leaseCount.Add(1)
+
+		// Unblock the sweep.
+		state.gcLock.Unlock()
+
+		// Wait for the sweep to complete.
+		select {
+		case <-sweepDone:
+			// Continue to assertion.
+		case <-time.After(time.Second):
+			t.Fatal("verifyAndSweepFlows deadlocked or timed out")
+		}
+
+		h.assertFlowExists(key, "Flow should not be collected because it became active before the sweep")
+		state.gcLock.Lock() // Re-lock for the deferred unlock.
+	})
+
+	t.Run("ShouldCollectDrainingShard_OnlyWhenEmpty", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{initialShardCount: 2})
+		key := types.FlowKey{ID: "flow-on-draining-shard", Priority: highPriority}
+		h.openConnectionOnFlow(key)
+
+		// Add an item to a queue on the soon-to-be Draining shard to keep it busy.
+		drainingShard := h.fr.activeShards[1] // The shard that will become draining.
+		mq, err := drainingShard.ManagedQueue(key)
+		require.NoError(t, err, "Test setup: getting queue on draining shard failed")
+		item := mocks.NewMockQueueItemAccessor(100, "req1", key)
+		require.NoError(t, mq.Add(item), "Adding item to non-active shard should be allowed for in-flight requests")
+
+		// Scale down to mark one shard as Draining.
+		require.NoError(t, h.fr.updateShardCount(1), "Test setup: scale down should succeed")
+		require.Len(t, h.fr.drainingShards, 1, "Test setup: one shard should be draining")
+
+		// Trigger a GC cycle while the shard is not empty.
+		h.fr.sweepDrainingShards()
+		require.Len(t, h.fr.drainingShards, 1, "Draining shard should not be collected while it is not empty")
+
+		// Empty the shard and trigger GC again.
+		_, err = mq.Remove(item.Handle())
+		require.NoError(t, err, "Test setup: removing item from draining shard failed")
+		h.fr.sweepDrainingShards()
+		assert.Empty(t, h.fr.drainingShards, "Draining shard should be collected after it becomes empty")
+	})
+
+	t.Run("ShouldHandleBenignRace_WhenSweepingAlreadyDeletedFlow", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{})
+		key := types.FlowKey{ID: "benign-race-flow", Priority: highPriority}
+		h.openConnectionOnFlow(key)
+
+		// Get the flow state so we can lock it.
+		val, ok := h.fr.flowStates.Load(key)
+		require.True(t, ok, "Test setup: flow state must exist")
+		state := val.(*flowState)
+
+		// Make the flow a candidate for GC.
+		h.fakeClock.Step(h.config.FlowGCTimeout + time.Second)
+		candidates := []types.FlowKey{key}
+
+		// Manually lock the flow's `gcLock`. This simulates the GC being stuck just before its "Verify" phase.
+		state.gcLock.Lock()
+		defer state.gcLock.Unlock()
+
+		// In a background goroutine, run the sweep. It will block on the lock.
+		sweepDone := make(chan struct{})
+		go func() {
+			defer close(sweepDone)
+			h.fr.verifyAndSweepFlows(candidates)
+		}()
+
+		// While the sweep is blocked, delete the flow from underneath it.
+		// This creates the benign race condition.
+		h.fr.flowStates.Delete(key)
+
+		// Unblock the sweep logic.
+		state.gcLock.Unlock() // Temporarily unlock to let the sweep proceed.
+
+		// The sweep must complete without panicking.
+		select {
+		case <-sweepDone:
+			// Success! The test completed gracefully.
+		case <-time.After(time.Second):
+			t.Fatal("verifyAndSweepFlows deadlocked or timed out")
+		}
+		state.gcLock.Lock() // Re-lock for the deferred unlock.
+	})
+}
+
+// --- Shard Management Tests ---
+
+func TestFlowRegistry_UpdateShardCount(t *testing.T) {
+	t.Parallel()
+	const (
+		globalCapacity = 100
+		bandCapacity   = 50
+	)
+	testCases := []struct {
+		name                                string
+		initialShardCount                   int
+		targetShardCount                    int
+		expectedActiveCount                 int
+		expectedPartitionedGlobalCapacities map[uint64]int
+		expectedPartitionedBandCapacities   map[uint64]int
+		expectErrIs                         error // Optional
+	}{
+		{
+			name:                                "NoOp_ScaleToSameCount",
+			initialShardCount:                   2,
+			targetShardCount:                    2,
+			expectedActiveCount:                 2,
+			expectedPartitionedGlobalCapacities: map[uint64]int{50: 2},
+			expectedPartitionedBandCapacities:   map[uint64]int{25: 2},
+		},
+		{
+			name:                                "Succeeds_ScaleUp_FromOne",
+			initialShardCount:                   1,
+			targetShardCount:                    4,
+			expectedActiveCount:                 4,
+			expectedPartitionedGlobalCapacities: map[uint64]int{25: 4},
+			expectedPartitionedBandCapacities:   map[uint64]int{12: 2, 13: 2},
+		},
+		{
+			name:                                "Succeeds_ScaleDown_ToOne",
+			initialShardCount:                   3,
+			targetShardCount:                    1,
+			expectedActiveCount:                 1,
+			expectedPartitionedGlobalCapacities: map[uint64]int{100: 1},
+			expectedPartitionedBandCapacities:   map[uint64]int{50: 1},
+		},
+		{
+			name:                                "Error_ScaleDown_ToZero",
+			initialShardCount:                   2,
+			targetShardCount:                    0,
+			expectedActiveCount:                 2,
+			expectErrIs:                         contracts.ErrInvalidShardCount,
+			expectedPartitionedGlobalCapacities: map[uint64]int{50: 2},
+			expectedPartitionedBandCapacities:   map[uint64]int{25: 2},
+		},
+		{
+			name:                                "Error_ScaleDown_ToNegative",
+			initialShardCount:                   1,
+			targetShardCount:                    -1,
+			expectedActiveCount:                 1,
+			expectErrIs:                         contracts.ErrInvalidShardCount,
+			expectedPartitionedGlobalCapacities: map[uint64]int{100: 1},
+			expectedPartitionedBandCapacities:   map[uint64]int{50: 1},
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
+			config := Config{
+				MaxBytes: globalCapacity,
+				PriorityBands: []PriorityBandConfig{
+					{Priority: highPriority, PriorityName: "A", MaxBytes: bandCapacity},
+				},
+				InitialShardCount: tc.initialShardCount,
+			}
+
+			h := newRegistryTestHarness(t, harnessOptions{config: &config})
+			key := types.FlowKey{ID: "flow", Priority: highPriority}
+			h.openConnectionOnFlow(key)
+
+			err := h.fr.updateShardCount(tc.targetShardCount)
+			if tc.expectErrIs != nil {
+				require.Error(t, err, "UpdateShardCount should have returned an error")
+				assert.ErrorIs(t, err, tc.expectErrIs, "Error should be the expected type")
+			} else {
+				require.NoError(t, err, "UpdateShardCount should not have returned an error")
+			}
+
+			globalCapacities := make(map[uint64]int)
+			bandCapacities := make(map[uint64]int)
+
+			h.fr.mu.RLock()
+			finalActiveCount := len(h.fr.activeShards)
+			finalDrainingCount := len(h.fr.drainingShards)
+			for _, shard := range h.fr.activeShards {
+				stats := shard.Stats()
+				globalCapacities[stats.TotalCapacityBytes]++
+				bandCapacities[stats.PerPriorityBandStats[highPriority].CapacityBytes]++
+				h.assertFlowExists(key, "Shard %s should contain the existing flow", shard.ID())
+			}
+			h.fr.mu.RUnlock()
+
+			expectedDrainingCount := 0
+			if tc.initialShardCount > tc.expectedActiveCount {
+				expectedDrainingCount = tc.initialShardCount - tc.expectedActiveCount
+			}
+			assert.Equal(t, tc.expectedActiveCount, finalActiveCount, "Final active shard count is incorrect")
+			assert.Equal(t, expectedDrainingCount, finalDrainingCount, "Final draining shard count in registry is incorrect")
+			assert.Equal(t, tc.expectedPartitionedGlobalCapacities, globalCapacities,
+				"Global capacity re-partitioning incorrect")
+			assert.Equal(t, tc.expectedPartitionedBandCapacities, bandCapacities, "Band capacity re-partitioning incorrect")
+		})
+	}
+}
+
+// --- Concurrency Tests ---
+
+func TestFlowRegistry_Concurrency(t *testing.T) {
+	t.Parallel()
+
+	t.Run("ConcurrentJITRegistrations_ShouldBeSafe", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{})
+		key := types.FlowKey{ID: "concurrent-flow", Priority: highPriority}
+		numGoroutines := 50
+		var wg sync.WaitGroup
+		wg.Add(numGoroutines)
+
+		// Hammer the `WithConnection` method for the same key from many goroutines.
+		for range numGoroutines {
+			go func() {
+				defer wg.Done()
+				err := h.fr.WithConnection(key, func(contracts.ActiveFlowConnection) error {
+					// Do a small amount of work inside the connection.
+					time.Sleep(1 * time.Millisecond)
+					return nil
+				})
+				require.NoError(t, err, "Concurrent WithConnection calls must not fail")
+			}()
+		}
+		wg.Wait()
+
+		// The primary assertion is that this completes without the race detector firing.
+		// We can also check that the flow state is consistent.
+		h.assertFlowExists(key, "Flow must exist after concurrent JIT registration")
+	})
+
+	t.Run("MixedAdminAndDataPlaneWorkload", func(t *testing.T) {
+		t.Parallel()
+		h := newRegistryTestHarness(t, harnessOptions{initialShardCount: 1})
+		const (
+			numWorkers    = 10
+			opsPerWorker  = 50
+			maxShardCount = 4
+		)
+
+		var wg sync.WaitGroup
+		wg.Add(numWorkers + 1) // +1 for the scaling goroutine
+
+		// Data Plane Workers: Constantly creating new flows.
+		for i := range numWorkers {
+			workerID := i
+			go func() {
+				defer wg.Done()
+				for j := range opsPerWorker {
+					key := types.FlowKey{ID: fmt.Sprintf("flow-%d-%d", workerID, j), Priority: highPriority}
+					_ = h.fr.WithConnection(key, func(contracts.ActiveFlowConnection) error { return nil })
+				}
+			}()
+		}
+
+		// Admin Worker: Constantly scaling the number of shards up and down.
+		go func() {
+			defer wg.Done()
+			for i := 1; i < maxShardCount; i++ {
+				_ = h.fr.updateShardCount(i + 1)
+				_ = h.fr.updateShardCount(i)
+			}
+		}()
+
+		wg.Wait()
+
+		// The test completing without a race condition is the primary assertion.
+		// We can also assert a consistent final state.
+		assert.Len(t, h.fr.activeShards, maxShardCount-1, "Final active shard count should be consistent")
+		flowCount := 0
+		h.fr.flowStates.Range(func(_, _ any) bool {
+			flowCount++
+			return true
+		})
+		assert.Equal(t, numWorkers*opsPerWorker, flowCount, "All concurrently registered flows must be present")
+	})
+}
diff --git a/pkg/epp/flowcontrol/registry/shard_test.go b/pkg/epp/flowcontrol/registry/shard_test.go
index b04bde4..23bf813 100644
--- a/pkg/epp/flowcontrol/registry/shard_test.go
+++ b/pkg/epp/flowcontrol/registry/shard_test.go
@@ -18,7 +18,8 @@ package registry
 
 import (
 	"errors"
-	"slices"
+	"fmt"
+	"sync"
 	"testing"
 
 	"github.com/go-logr/logr"
@@ -28,313 +29,511 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/contracts"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework"
 	inter "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/interflow/dispatch"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/interflow/dispatch/besthead"
 	intra "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/policies/intraflow/dispatch/fcfs"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/queue"
-	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/framework/plugins/queue/listqueue"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types/mocks"
 )
 
-// shardTestFixture holds the components needed for a `registryShard` test.
-type shardTestFixture struct {
-	config *Config
-	shard  *registryShard
+const (
+	// highPriority is the priority level for the "High" priority band in the test harness config.
+	highPriority int = 20
+	// lowPriority is the priority level for the "Low" priority band in the test harness config.
+	lowPriority int = 10
+	// nonExistentPriority is a priority that is known not to exist in the test harness config.
+	nonExistentPriority int = 99
+)
+
+// --- Test Harness and Mocks ---
+
+// shardTestHarness holds all components for a `registryShard` test.
+type shardTestHarness struct {
+	t                *testing.T
+	shard            *registryShard
+	statsPropagator  *mockStatsPropagator
+	highPriorityKey1 types.FlowKey
+	highPriorityKey2 types.FlowKey
+	lowPriorityKey   types.FlowKey
 }
 
-// setupTestShard creates a new test fixture for testing the `registryShard`.
-func setupTestShard(t *testing.T) *shardTestFixture {
+// newShardTestHarness initializes a `shardTestHarness` with a default configuration.
+func newShardTestHarness(t *testing.T) *shardTestHarness {
 	t.Helper()
-
-	config := &Config{
+	globalConfig, err := newConfig(Config{
 		PriorityBands: []PriorityBandConfig{
-			{
-				Priority:     10,
-				PriorityName: "High",
-			},
-			{
-				Priority:     20,
-				PriorityName: "Low",
-			},
+			{Priority: highPriority, PriorityName: "High"},
+			{Priority: lowPriority, PriorityName: "Low"},
 		},
+	})
+	require.NoError(t, err, "Test setup: validating and defaulting config should not fail")
+
+	statsPropagator := &mockStatsPropagator{}
+	shardConfig := globalConfig.partition(0, 1)
+	shard, err := newShard(
+		"test-shard-1",
+		shardConfig, logr.Discard(),
+		statsPropagator.propagate,
+		inter.NewPolicyFromName,
+	)
+	require.NoError(t, err, "Test setup: newShard should not return an error with valid configuration")
+
+	h := &shardTestHarness{
+		t:                t,
+		shard:            shard,
+		statsPropagator:  statsPropagator,
+		highPriorityKey1: types.FlowKey{ID: "hp-flow-1", Priority: highPriority},
+		highPriorityKey2: types.FlowKey{ID: "hp-flow-2", Priority: highPriority},
+		lowPriorityKey:   types.FlowKey{ID: "lp-flow-1", Priority: lowPriority},
 	}
-	// Apply defaults to the master config first, as the parent registry would.
-	err := config.validateAndApplyDefaults()
-	require.NoError(t, err, "Setup: validating and defaulting config should not fail")
-
-	// The parent registry would partition the config. For a single shard test, we can use the defaulted one directly.
-	shard, err := newShard("test-shard-1", config, logr.Discard(), nil)
-	require.NoError(t, err, "Setup: newShard should not return an error")
-	require.NotNil(t, shard, "Setup: newShard should return a non-nil shard")
-
-	return &shardTestFixture{
-		config: config,
-		shard:  shard,
-	}
+	// Automatically sync some default flows for convenience.
+	h.synchronizeFlow(h.highPriorityKey1)
+	h.synchronizeFlow(h.highPriorityKey2)
+	h.synchronizeFlow(h.lowPriorityKey)
+	return h
 }
 
-// _reconcileFlow_testOnly is a test helper that simulates the future admin logic for adding or updating a flow.
-// It creates a `managedQueue` and correctly populates the `priorityBands` map and the `flowKeys` slice.
-// This helper is intended to be replaced by the real `reconcileFlow` method in a future PR.
-func (s *registryShard) _reconcileFlow_testOnly(
-	t *testing.T,
-	flowSpec types.FlowSpecification,
-) *managedQueue {
-	t.Helper()
-
-	band, ok := s.priorityBands[flowSpec.Key.Priority]
-	require.True(t, ok, "Setup: priority band %d should exist", flowSpec.Key.Priority)
-
-	lq, err := queue.NewQueueFromName(listqueue.ListQueueName, nil)
-	require.NoError(t, err, "Setup: creating a real listqueue should not fail")
-
-	mq := newManagedQueue(
-		lq,
-		band.defaultIntraFlowDispatchPolicy,
-		flowSpec.Key,
-		logr.Discard(),
-		func(lenDelta, byteSizeDelta int64) { s.reconcileStats(flowSpec.Key.Priority, lenDelta, byteSizeDelta) },
-	)
-	require.NotNil(t, mq, "Setup: newManagedQueue should not return nil")
-
-	// Add the queue to the map and update the cached key slice.
-	band.queues[flowSpec.Key] = mq
-	band.flowKeys = append(band.flowKeys, flowSpec.Key)
-
-	return mq
+// synchronizeFlow simulates the registry synchronizing a flow with a real queue.
+func (h *shardTestHarness) synchronizeFlow(key types.FlowKey) {
+	h.t.Helper()
+	spec := types.FlowSpecification{Key: key}
+	policy, err := intra.NewPolicyFromName(defaultIntraFlowDispatchPolicy)
+	require.NoError(h.t, err, "Helper synchronizeFlow: failed to create real intra-flow policy for synchronization")
+	q, err := queue.NewQueueFromName(defaultQueue, policy.Comparator())
+	require.NoError(h.t, err, "Helper synchronizeFlow: failed to create real queue for synchronization")
+	h.shard.synchronizeFlow(spec, policy, q)
 }
 
-func TestNewShard(t *testing.T) {
-	t.Parallel()
-	f := setupTestShard(t)
-
-	assert.Equal(t, "test-shard-1", f.shard.ID(), "ID should be set correctly")
-	assert.True(t, f.shard.IsActive(), "A new shard should be active")
-	require.Len(t, f.shard.priorityBands, 2, "Should have 2 priority bands")
-
-	// Check that priority levels are sorted correctly
-	assert.Equal(t, []uint{10, 20}, f.shard.AllOrderedPriorityLevels(), "Priority levels should be ordered")
-
-	// Check band 10
-	band10, ok := f.shard.priorityBands[10]
-	require.True(t, ok, "Priority band 10 should exist")
-	assert.Equal(t, uint(10), band10.config.Priority, "Band 10 should have correct priority")
-	assert.Equal(t, "High", band10.config.PriorityName, "Band 10 should have correct name")
-	assert.NotNil(t, band10.interFlowDispatchPolicy, "Inter-flow policy for band 10 should be instantiated")
-	assert.NotNil(t, band10.defaultIntraFlowDispatchPolicy,
-		"Default intra-flow policy for band 10 should be instantiated")
-	assert.Equal(t, besthead.BestHeadPolicyName, band10.interFlowDispatchPolicy.Name(),
-		"Correct default inter-flow policy should be used")
-	assert.Equal(t, fcfs.FCFSPolicyName, band10.defaultIntraFlowDispatchPolicy.Name(),
-		"Correct default intra-flow policy should be used")
-
-	// Check band 20
-	band20, ok := f.shard.priorityBands[20]
-	require.True(t, ok, "Priority band 20 should exist")
-	assert.Equal(t, uint(20), band20.config.Priority, "Band 20 should have correct priority")
-	assert.Equal(t, "Low", band20.config.PriorityName, "Band 20 should have correct name")
-	assert.NotNil(t, band20.interFlowDispatchPolicy, "Inter-flow policy for band 20 should be instantiated")
-	assert.NotNil(t, band20.defaultIntraFlowDispatchPolicy,
-		"Default intra-flow policy for band 20 should be instantiated")
+// addItem adds an item to a specific flow's queue on the shard.
+func (h *shardTestHarness) addItem(key types.FlowKey, size uint64) types.QueueItemAccessor {
+	h.t.Helper()
+	mq, err := h.shard.ManagedQueue(key)
+	require.NoError(h.t, err, "Helper addItem: failed to get queue for flow %s; ensure flow is synchronized", key)
+	item := mocks.NewMockQueueItemAccessor(size, "req", key)
+	require.NoError(h.t, mq.Add(item), "Helper addItem: failed to add item to queue for flow %s", key)
+	return item
 }
 
-// TestNewShard_ErrorPaths modifies global plugin registries, so it cannot be run in parallel with other tests.
-func TestNewShard_ErrorPaths(t *testing.T) {
-	baseConfig := &Config{
-		PriorityBands: []PriorityBandConfig{{
-			Priority:                10,
-			PriorityName:            "High",
-			IntraFlowDispatchPolicy: fcfs.FCFSPolicyName,
-			InterFlowDispatchPolicy: besthead.BestHeadPolicyName,
-			Queue:                   listqueue.ListQueueName,
-		}},
-	}
-	require.NoError(t, baseConfig.validateAndApplyDefaults(), "Setup: base config should be valid")
+// removeItem removes an item from a specific flow's queue.
+func (h *shardTestHarness) removeItem(key types.FlowKey, item types.QueueItemAccessor) {
+	h.t.Helper()
+	mq, err := h.shard.ManagedQueue(key)
+	require.NoError(h.t, err, "Helper removeItem: failed to get queue for flow %s; ensure flow is synchronized", key)
+	_, err = mq.Remove(item.Handle())
+	require.NoError(h.t, err, "Helper removeItem: failed to remove item from queue for flow %s", key)
+}
 
-	t.Run("Invalid InterFlow Policy", func(t *testing.T) {
-		// Register a mock policy that always fails to instantiate
-		failingPolicyName := inter.RegisteredPolicyName("failing-inter-policy")
-		inter.MustRegisterPolicy(failingPolicyName, func() (framework.InterFlowDispatchPolicy, error) {
-			return nil, errors.New("inter-flow instantiation failed")
-		})
+// --- Basic Tests ---
 
-		badConfig := *baseConfig
-		badConfig.PriorityBands[0].InterFlowDispatchPolicy = failingPolicyName
+func TestShard_New(t *testing.T) {
+	t.Parallel()
 
-		_, err := newShard("test", &badConfig, logr.Discard(), nil)
-		require.Error(t, err, "newShard should fail with an invalid inter-flow policy")
+	t.Run("ShouldInitializeCorrectly_WithDefaultConfig", func(t *testing.T) {
+		t.Parallel()
+		h := newShardTestHarness(t)
+
+		assert.Equal(t, "test-shard-1", h.shard.ID(), "Shard ID must match the value provided during construction")
+		assert.True(t, h.shard.IsActive(), "A newly created shard must be initialized in the Active state")
+		assert.Equal(t, []int{highPriority, lowPriority}, h.shard.AllOrderedPriorityLevels(),
+			"Shard must report configured priority levels sorted numerically (highest priority first)")
+
+		bandHigh, ok := h.shard.priorityBands[highPriority]
+		require.True(t, ok, "Priority band %d (High) must be initialized", highPriority)
+		assert.Equal(t, "High", bandHigh.config.PriorityName, "Priority band name must match the configuration")
+		require.NotNil(t, bandHigh.interFlowDispatchPolicy, "Inter-flow policy must be instantiated during construction")
+		assert.Equal(t, string(defaultInterFlowDispatchPolicy), bandHigh.interFlowDispatchPolicy.Name(),
+			"The default inter-flow policy implementation must be used when not overridden")
 	})
 
-	t.Run("Invalid IntraFlow Policy", func(t *testing.T) {
-		// Register a mock policy that always fails to instantiate
-		failingPolicyName := intra.RegisteredPolicyName("failing-intra-policy")
-		intra.MustRegisterPolicy(failingPolicyName, func() (framework.IntraFlowDispatchPolicy, error) {
-			return nil, errors.New("intra-flow instantiation failed")
-		})
-
-		badConfig := *baseConfig
-		badConfig.PriorityBands[0].IntraFlowDispatchPolicy = failingPolicyName
-
-		_, err := newShard("test", &badConfig, logr.Discard(), nil)
-		require.Error(t, err, "newShard should fail with an invalid intra-flow policy")
+	t.Run("ShouldFail_WhenInterFlowPolicyFactoryFails", func(t *testing.T) {
+		t.Parallel()
+		shardConfig, _ := newConfig(Config{PriorityBands: []PriorityBandConfig{
+			{Priority: highPriority, PriorityName: "High"},
+		}})
+		failingFactory := func(inter.RegisteredPolicyName) (framework.InterFlowDispatchPolicy, error) {
+			return nil, errors.New("policy not found")
+		}
+		_, err := newShard("test-shard-1", shardConfig.partition(0, 1), logr.Discard(), nil, failingFactory)
+		require.Error(t, err, "newShard must fail if the inter-flow policy cannot be instantiated during initialization")
 	})
 }
 
 func TestShard_Stats(t *testing.T) {
 	t.Parallel()
-	f := setupTestShard(t)
-
-	// Add a queue and some items to test stats aggregation
-	flowKey := types.FlowKey{ID: "flow1", Priority: 10}
-	mq := f.shard._reconcileFlow_testOnly(t, types.FlowSpecification{Key: flowKey})
-
-	// Add items
-	require.NoError(t, mq.Add(mocks.NewMockQueueItemAccessor(100, "req1", flowKey)), "Adding item should not fail")
-	require.NoError(t, mq.Add(mocks.NewMockQueueItemAccessor(50, "req2", flowKey)), "Adding item should not fail")
-
-	stats := f.shard.Stats()
-
-	// Check shard-level stats
-	assert.Equal(t, uint64(2), stats.TotalLen, "Total length should be 2")
-	assert.Equal(t, uint64(150), stats.TotalByteSize, "Total byte size should be 150")
-
-	// Check per-band stats
-	require.Len(t, stats.PerPriorityBandStats, 2, "Should have stats for 2 bands")
-	band10Stats := stats.PerPriorityBandStats[10]
-	assert.Equal(t, uint(10), band10Stats.Priority, "Band 10 stats should have correct priority")
-	assert.Equal(t, uint64(2), band10Stats.Len, "Band 10 length should be 2")
-	assert.Equal(t, uint64(150), band10Stats.ByteSize, "Band 10 byte size should be 150")
-
-	band20Stats := stats.PerPriorityBandStats[20]
-	assert.Equal(t, uint(20), band20Stats.Priority, "Band 20 stats should have correct priority")
-	assert.Zero(t, band20Stats.Len, "Band 20 length should be 0")
-	assert.Zero(t, band20Stats.ByteSize, "Band 20 byte size should be 0")
+	h := newShardTestHarness(t)
+	h.addItem(h.highPriorityKey1, 100)
+	h.addItem(h.highPriorityKey1, 50)
+
+	stats := h.shard.Stats()
+
+	assert.Equal(t, h.shard.ID(), stats.ID, "Stats ID must match the shard ID")
+	assert.True(t, stats.IsActive, "Shard must report itself as active in the stats snapshot")
+	assert.Equal(t, uint64(2), stats.TotalLen, "Total shard length must aggregate counts from all bands")
+	assert.Equal(t, uint64(150), stats.TotalByteSize, "Total shard byte size must aggregate sizes from all bands")
+
+	bandHighStats, ok := stats.PerPriorityBandStats[highPriority]
+	require.True(t, ok, "Stats snapshot must include entries for all configured priority bands (e.g., %d)", highPriority)
+	assert.Equal(t, uint64(2), bandHighStats.Len, "Priority band length must reflect the items queued at that level")
+	assert.Equal(t, uint64(150), bandHighStats.ByteSize,
+		"Priority band byte size must reflect the items queued at that level")
 }
 
 func TestShard_Accessors(t *testing.T) {
 	t.Parallel()
-	f := setupTestShard(t)
-
-	key1 := types.FlowKey{ID: "flow1", Priority: 10}
-	key2 := types.FlowKey{ID: "flow2", Priority: 20}
 
-	// Setup state
-	queue1 := f.shard._reconcileFlow_testOnly(t, types.FlowSpecification{Key: key1})
-	f.shard._reconcileFlow_testOnly(t, types.FlowSpecification{Key: key2})
-
-	t.Run("ManagedQueue", func(t *testing.T) {
+	t.Run("SuccessPaths", func(t *testing.T) {
 		t.Parallel()
-		retrievedQueue, err := f.shard.ManagedQueue(key1)
-		require.NoError(t, err, "ManagedQueue should not error for an existing key")
-		assert.Same(t, queue1, retrievedQueue, "Should return the correct queue")
-
-		_, err = f.shard.ManagedQueue(types.FlowKey{ID: "non-existent", Priority: 10})
-		require.Error(t, err, "ManagedQueue should error for a non-existent flow key")
-		assert.ErrorIs(t, err, contracts.ErrFlowInstanceNotFound, "Error should be ErrFlowInstanceNotFound")
+		h := newShardTestHarness(t)
 
-		_, err = f.shard.ManagedQueue(types.FlowKey{ID: "flow1", Priority: 99}) // Non-existent priority
-		require.Error(t, err, "ManagedQueue should error for a non-existent priority")
-		assert.ErrorIs(t, err, contracts.ErrPriorityBandNotFound, "Error should be ErrPriorityBandNotFound")
-	})
+		t.Run("ManagedQueue", func(t *testing.T) {
+			t.Parallel()
+			mq, err := h.shard.ManagedQueue(h.highPriorityKey1)
+			require.NoError(t, err, "ManagedQueue accessor must succeed for a synchronized flow")
+			require.NotNil(t, mq, "Returned ManagedQueue must not be nil")
+			assert.Equal(t, h.highPriorityKey1, mq.FlowQueueAccessor().FlowKey(),
+				"The returned queue instance must correspond to the requested FlowKey")
+		})
 
-	t.Run("IntraFlowDispatchPolicy", func(t *testing.T) {
-		t.Parallel()
-		retrievedPolicy, err := f.shard.IntraFlowDispatchPolicy(key1)
-		require.NoError(t, err, "IntraFlowDispatchPolicy should not error for an existing key")
-		assert.Same(t, queue1.dispatchPolicy, retrievedPolicy, "Should return the policy from the correct instance")
+		t.Run("IntraFlowDispatchPolicy", func(t *testing.T) {
+			t.Parallel()
+			policy, err := h.shard.IntraFlowDispatchPolicy(h.highPriorityKey1)
+			require.NoError(t, err, "IntraFlowDispatchPolicy accessor must succeed for a synchronized flow")
+			require.NotNil(t, policy, "Returned policy must not be nil (guaranteed by contract)")
+			assert.Equal(t, string(defaultIntraFlowDispatchPolicy), policy.Name(),
+				"Must return the default intra-flow policy implementation")
+		})
 
-		_, err = f.shard.IntraFlowDispatchPolicy(types.FlowKey{ID: "non-existent", Priority: 10})
-		require.Error(t, err, "IntraFlowDispatchPolicy should error for a non-existent flow")
-		assert.ErrorIs(t, err, contracts.ErrFlowInstanceNotFound, "Error should be ErrFlowInstanceNotFound")
+		t.Run("InterFlowDispatchPolicy", func(t *testing.T) {
+			t.Parallel()
+			policy, err := h.shard.InterFlowDispatchPolicy(highPriority)
+			require.NoError(t, err, "InterFlowDispatchPolicy accessor must succeed for a configured priority band")
+			require.NotNil(t, policy, "Returned policy must not be nil (guaranteed by contract)")
+			assert.Equal(t, string(defaultInterFlowDispatchPolicy), policy.Name(),
+				"Must return the default inter-flow policy implementation")
+		})
 	})
 
-	t.Run("InterFlowDispatchPolicy", func(t *testing.T) {
+	t.Run("ErrorPaths", func(t *testing.T) {
 		t.Parallel()
-		retrievedInterPolicy, err := f.shard.InterFlowDispatchPolicy(10)
-		require.NoError(t, err, "InterFlowDispatchPolicy should not error for an existing priority")
-		assert.Same(t, f.shard.priorityBands[10].interFlowDispatchPolicy, retrievedInterPolicy,
-			"Should return the correct inter-flow policy")
-
-		_, err = f.shard.InterFlowDispatchPolicy(99) // Non-existent priority
-		require.Error(t, err, "InterFlowDispatchPolicy should error for a non-existent priority")
-		assert.ErrorIs(t, err, contracts.ErrPriorityBandNotFound, "Error should be ErrPriorityBandNotFound")
+		testCases := []struct {
+			name      string
+			action    func(s *registryShard) error
+			expectErr error
+		}{
+			{
+				name: "ManagedQueue_PriorityNotFound",
+				action: func(s *registryShard) error {
+					_, err := s.ManagedQueue(types.FlowKey{Priority: nonExistentPriority})
+					return err
+				},
+				expectErr: contracts.ErrPriorityBandNotFound,
+			},
+			{
+				name: "ManagedQueue_FlowNotFound",
+				action: func(s *registryShard) error {
+					_, err := s.ManagedQueue(types.FlowKey{ID: "missing", Priority: highPriority})
+					return err
+				},
+				expectErr: contracts.ErrFlowInstanceNotFound,
+			},
+			{
+				name: "InterFlowDispatchPolicy_PriorityNotFound",
+				action: func(s *registryShard) error {
+					_, err := s.InterFlowDispatchPolicy(nonExistentPriority)
+					return err
+				},
+				expectErr: contracts.ErrPriorityBandNotFound,
+			},
+			{
+				name: "IntraFlowDispatchPolicy_PriorityNotFound",
+				action: func(s *registryShard) error {
+					_, err := s.IntraFlowDispatchPolicy(types.FlowKey{Priority: nonExistentPriority})
+					return err
+				},
+				expectErr: contracts.ErrPriorityBandNotFound,
+			},
+			{
+				name: "IntraFlowDispatchPolicy_FlowNotFound",
+				action: func(s *registryShard) error {
+					_, err := s.IntraFlowDispatchPolicy(types.FlowKey{ID: "missing", Priority: highPriority})
+					return err
+				},
+				expectErr: contracts.ErrFlowInstanceNotFound,
+			},
+		}
+		for _, tc := range testCases {
+			t.Run(tc.name, func(t *testing.T) {
+				t.Parallel()
+				h := newShardTestHarness(t)
+				err := tc.action(h.shard)
+				require.Error(t, err, "The accessor method must return an error for this scenario")
+				assert.ErrorIs(t, err, tc.expectErr,
+					"The error must wrap the specific sentinel error defined in the contracts package")
+			})
+		}
 	})
 }
 
 func TestShard_PriorityBandAccessor(t *testing.T) {
 	t.Parallel()
-	f := setupTestShard(t)
-
-	// Setup shard state for the tests
-	p1, p2 := uint(10), uint(20)
-	key1P1 := types.FlowKey{ID: "flow1", Priority: p1}
-	key1P2 := types.FlowKey{ID: "flow1", Priority: p2}
-	key2P2 := types.FlowKey{ID: "flow2", Priority: p2}
 
-	f.shard._reconcileFlow_testOnly(t, types.FlowSpecification{Key: key1P1})
-	f.shard._reconcileFlow_testOnly(t, types.FlowSpecification{Key: key1P2})
-	f.shard._reconcileFlow_testOnly(t, types.FlowSpecification{Key: key2P2})
+	t.Run("ShouldFail_WhenPriorityDoesNotExist", func(t *testing.T) {
+		t.Parallel()
+		h := newShardTestHarness(t)
+		_, err := h.shard.PriorityBandAccessor(nonExistentPriority)
+		assert.ErrorIs(t, err, contracts.ErrPriorityBandNotFound,
+			"Requesting an accessor for an unconfigured priority must fail with ErrPriorityBandNotFound")
+	})
 
-	t.Run("Accessor for existing priority", func(t *testing.T) {
+	t.Run("ShouldSucceed_WhenPriorityExists", func(t *testing.T) {
 		t.Parallel()
-		accessor, err := f.shard.PriorityBandAccessor(p2)
-		require.NoError(t, err, "PriorityBandAccessor should not fail for existing priority")
-		require.NotNil(t, accessor, "Accessor should not be nil")
+		h := newShardTestHarness(t)
+		accessor, err := h.shard.PriorityBandAccessor(h.highPriorityKey1.Priority)
+		require.NoError(t, err, "Requesting an accessor for a configured priority must succeed")
+		require.NotNil(t, accessor, "The returned accessor instance must not be nil")
 
-		t.Run("Properties", func(t *testing.T) {
+		t.Run("Properties_ShouldReturnCorrectValues", func(t *testing.T) {
 			t.Parallel()
-			assert.Equal(t, p2, accessor.Priority(), "Accessor should have correct priority")
-			assert.Equal(t, "Low", accessor.PriorityName(), "Accessor should have correct priority name")
+			assert.Equal(t, h.highPriorityKey1.Priority, accessor.Priority(),
+				"Accessor Priority() must match the configured numerical priority")
+			assert.Equal(t, "High", accessor.PriorityName(), "Accessor PriorityName() must match the configured name")
 		})
 
-		t.Run("FlowKeys", func(t *testing.T) {
+		t.Run("FlowKeys_ShouldReturnAllKeysInBand", func(t *testing.T) {
 			t.Parallel()
-			flowKeys := accessor.FlowKeys()
-			// Sort for consistent comparison as map iteration order is not guaranteed.
-			slices.SortFunc(flowKeys, func(a, b types.FlowKey) int {
-				return a.Compare(b)
-			})
-			assert.Equal(t, []types.FlowKey{key1P2, key2P2}, flowKeys,
-				"Accessor should return correct flow keys for the priority band")
+			keys := accessor.FlowKeys()
+			expectedKeys := []types.FlowKey{h.highPriorityKey1, h.highPriorityKey2}
+			assert.ElementsMatch(t, expectedKeys, keys,
+				"FlowKeys() must return a complete snapshot of all flows registered in this band")
 		})
 
-		t.Run("Queue", func(t *testing.T) {
+		t.Run("Queue_ShouldReturnCorrectAccessor", func(t *testing.T) {
 			t.Parallel()
-			q := accessor.Queue("flow1")
-			require.NotNil(t, q, "Accessor should return queue for flow1")
-			assert.Equal(t, p2, q.FlowKey().Priority, "Queue should have the correct priority")
-			assert.Nil(t, accessor.Queue("non-existent"), "Accessor should return nil for non-existent flow")
+			q := accessor.Queue(h.highPriorityKey1.ID)
+			require.NotNil(t, q, "Queue() must return a non-nil accessor for a registered flow ID")
+			assert.Equal(t, h.highPriorityKey1, q.FlowKey(), "The returned queue accessor must have the correct FlowKey")
+			assert.Nil(t, accessor.Queue("non-existent"), "Queue() must return nil if the flow ID is not found in this band")
 		})
 
 		t.Run("IterateQueues", func(t *testing.T) {
 			t.Parallel()
-			var iteratedKeys []types.FlowKey
-			accessor.IterateQueues(func(queue framework.FlowQueueAccessor) bool {
-				iteratedKeys = append(iteratedKeys, queue.FlowKey())
-				return true
+
+			t.Run("ShouldVisitAllQueuesInBand", func(t *testing.T) {
+				t.Parallel()
+				var iteratedKeys []types.FlowKey
+				accessor.IterateQueues(func(queue framework.FlowQueueAccessor) bool {
+					iteratedKeys = append(iteratedKeys, queue.FlowKey())
+					return true
+				})
+				expectedKeys := []types.FlowKey{h.highPriorityKey1, h.highPriorityKey2}
+				assert.ElementsMatch(t, expectedKeys, iteratedKeys,
+					"IterateQueues must visit every registered flow in the band exactly once")
+			})
+
+			t.Run("ShouldExitEarly_WhenCallbackReturnsFalse", func(t *testing.T) {
+				t.Parallel()
+				var iterationCount int
+				accessor.IterateQueues(func(queue framework.FlowQueueAccessor) bool {
+					iterationCount++
+					return false
+				})
+				assert.Equal(t, 1, iterationCount, "IterateQueues must terminate immediately when the callback returns false")
 			})
-			slices.SortFunc(iteratedKeys, func(a, b types.FlowKey) int {
-				return a.Compare(b)
+
+			t.Run("ShouldBeSafe_DuringConcurrentMapModification", func(t *testing.T) {
+				t.Parallel()
+				h := newShardTestHarness(t) // Isolated harness to avoid corrupting the state for other parallel tests
+				accessor, err := h.shard.PriorityBandAccessor(highPriority)
+				require.NoError(t, err)
+
+				var wg sync.WaitGroup
+				wg.Add(2)
+
+				// Goroutine A: The Iterator (constantly reading)
+				go func() {
+					defer wg.Done()
+					for i := 0; i < 100; i++ {
+						accessor.IterateQueues(func(queue framework.FlowQueueAccessor) bool {
+							// Accessing data should not panic or race.
+							_ = queue.FlowKey()
+							return true
+						})
+					}
+				}()
+
+				// Goroutine B: The Modifier (constantly writing)
+				go func() {
+					defer wg.Done()
+					for i := 0; i < 100; i++ {
+						key := types.FlowKey{ID: fmt.Sprintf("new-flow-%d", i), Priority: highPriority}
+						h.synchronizeFlow(key)
+						h.shard.deleteFlow(key)
+					}
+				}()
+
+				// The primary assertion is that this test completes without the race detector firing, which proves the
+				// `RLock/WLock` separation is correct.
+				wg.Wait()
 			})
-			assert.Equal(t, []types.FlowKey{key1P2, key2P2}, iteratedKeys, "IterateQueues should visit all flows in the band")
 		})
 
-		t.Run("IterateQueues with early exit", func(t *testing.T) {
+		t.Run("OnEmptyBand", func(t *testing.T) {
 			t.Parallel()
-			var iteratedKeys []types.FlowKey
+			h := newShardTestHarness(t)
+			h.shard.deleteFlow(h.lowPriorityKey)
+			accessor, err := h.shard.PriorityBandAccessor(lowPriority)
+			require.NoError(t, err, "Setup: getting an accessor for an empty band must succeed")
+
+			keys := accessor.FlowKeys()
+			assert.NotNil(t, keys, "FlowKeys() on an empty band must return a non-nil slice")
+			assert.Empty(t, keys, "FlowKeys() on an empty band must return an empty slice")
+
+			var callbackExecuted bool
 			accessor.IterateQueues(func(queue framework.FlowQueueAccessor) bool {
-				iteratedKeys = append(iteratedKeys, queue.FlowKey())
-				return false // Exit after first item
+				callbackExecuted = true
+				return true
 			})
-			assert.Len(t, iteratedKeys, 1, "IterateQueues should exit early if callback returns false")
+			assert.False(t, callbackExecuted, "IterateQueues must not execute the callback for an empty band")
 		})
 	})
+}
 
-	t.Run("Error on non-existent priority", func(t *testing.T) {
-		t.Parallel()
-		_, err := f.shard.PriorityBandAccessor(99)
-		require.Error(t, err, "PriorityBandAccessor should fail for non-existent priority")
-		assert.ErrorIs(t, err, contracts.ErrPriorityBandNotFound, "Error should be ErrPriorityBandNotFound")
-	})
+// --- Lifecycle and State Management Tests ---
+
+func TestShard_SynchronizeFlow(t *testing.T) {
+	t.Parallel()
+	h := newShardTestHarness(t)
+	flowKey := types.FlowKey{ID: "flow1", Priority: highPriority}
+
+	h.synchronizeFlow(flowKey)
+	mq1, err := h.shard.ManagedQueue(flowKey)
+	require.NoError(t, err, "Flow instance should be accessible after synchronization")
+
+	h.synchronizeFlow(flowKey)
+	mq2, err := h.shard.ManagedQueue(flowKey)
+	require.NoError(t, err, "Flow instance should remain accessible after idempotent re-synchronization")
+	assert.Same(t, mq1, mq2, "Idempotent synchronization must not replace the existing queue instance")
+}
+
+func TestShard_DeleteFlow(t *testing.T) {
+	t.Parallel()
+	h := newShardTestHarness(t)
+	_, err := h.shard.ManagedQueue(h.highPriorityKey1)
+	require.NoError(t, err, "Test setup: flow instance must exist before deletion")
+
+	h.shard.deleteFlow(h.highPriorityKey1)
+
+	_, err = h.shard.ManagedQueue(h.highPriorityKey1)
+	require.Error(t, err, "Flow instance should not be accessible after deletion")
+	assert.ErrorIs(t, err, contracts.ErrFlowInstanceNotFound,
+		"Accessing a deleted flow must return ErrFlowInstanceNotFound")
+}
+
+func TestShard_MarkAsDraining(t *testing.T) {
+	t.Parallel()
+	h := newShardTestHarness(t)
+	assert.True(t, h.shard.IsActive(), "Shard should be active initially")
+
+	h.shard.markAsDraining()
+	assert.False(t, h.shard.IsActive(), "Shard must report IsActive as false after being marked for draining")
+
+	h.shard.markAsDraining()
+	assert.False(t, h.shard.IsActive(), "Marking as draining should be idempotent")
+}
+
+// --- Concurrency Test ---
+
+// TestShard_Concurrency_MixedWorkload is a general stability test that simulates a realistic workload by having
+// concurrent readers (e.g., dispatchers) and writers operating on the same shard.
+// It provides high confidence that the fine-grained locking strategy is free of deadlocks and data races under
+// sustained, mixed contention.
+func TestShard_Concurrency_MixedWorkload(t *testing.T) {
+	t.Parallel()
+	const (
+		numReaders   = 5
+		numWriters   = 2
+		opsPerWriter = 100
+	)
+
+	h := newShardTestHarness(t)
+	stopCh := make(chan struct{})
+	var readersWg, writersWg sync.WaitGroup
+
+	readersWg.Add(numReaders)
+	for range numReaders {
+		go func() {
+			defer readersWg.Done()
+			for {
+				select {
+				case <-stopCh:
+					return
+				default:
+					for _, priority := range h.shard.AllOrderedPriorityLevels() {
+						accessor, err := h.shard.PriorityBandAccessor(priority)
+						if err == nil {
+							accessor.IterateQueues(func(q framework.FlowQueueAccessor) bool { return true })
+						}
+					}
+				}
+			}
+		}()
+	}
+
+	writersWg.Add(numWriters)
+	for range numWriters {
+		go func() {
+			defer writersWg.Done()
+			for j := range opsPerWriter {
+				// Alternate writing to different flows and priorities to increase contention.
+				if j%2 == 0 {
+					item := h.addItem(h.highPriorityKey1, 10)
+					h.removeItem(h.highPriorityKey1, item)
+				} else {
+					item := h.addItem(h.lowPriorityKey, 5)
+					h.removeItem(h.lowPriorityKey, item)
+				}
+			}
+		}()
+	}
+
+	// Wait for all writers to complete first.
+	writersWg.Wait()
+
+	// Now stop the readers and wait for them to exit.
+	close(stopCh)
+	readersWg.Wait()
+
+	// The primary assertion is that this test completes without the race detector firing; however, we can make some final
+	// assertions on state consistency.
+	finalStats := h.shard.Stats()
+	assert.Zero(t, finalStats.TotalLen, "After all paired add/remove operations, the total length should be zero")
+	assert.Zero(t, finalStats.TotalByteSize, "After all paired add/remove operations, the total byte size should be zero")
+}
+
+// --- Invariant Tests ---
+
+func TestShard_InvariantPanics(t *testing.T) {
+	t.Parallel()
+
+	testCases := []struct {
+		name   string
+		action func(h *shardTestHarness)
+	}{
+		{
+			name:   "OnStatsPropagatedForUnknownPriority",
+			action: func(h *shardTestHarness) { h.shard.propagateStatsDelta(nonExistentPriority, 1, 1) },
+		},
+		{
+			name:   "OnSynchronizingFlowWithMissingPriority",
+			action: func(h *shardTestHarness) { h.synchronizeFlow(types.FlowKey{ID: "flow", Priority: nonExistentPriority}) },
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
+			h := newShardTestHarness(t)
+			assert.Panics(t, func() { tc.action(h) },
+				"The action must trigger a panic when a critical system invariant is violated")
+		})
+	}
 }
diff --git a/pkg/epp/metrics/metrics_test.go b/pkg/epp/metrics/metrics_test.go
index f16183d..837fb8b 100644
--- a/pkg/epp/metrics/metrics_test.go
+++ b/pkg/epp/metrics/metrics_test.go
@@ -30,15 +30,15 @@ import (
 )
 
 const (
-	RequestTotalMetric                 = InferenceModelComponent + "_request_total"
-	RequestErrorTotalMetric            = InferenceModelComponent + "_request_error_total"
-	RequestLatenciesMetric             = InferenceModelComponent + "_request_duration_seconds"
-	RequestSizesMetric                 = InferenceModelComponent + "_request_sizes"
-	ResponseSizesMetric                = InferenceModelComponent + "_response_sizes"
-	InputTokensMetric                  = InferenceModelComponent + "_input_tokens"
-	OutputTokensMetric                 = InferenceModelComponent + "_output_tokens"
-	NormalizedTimePerOutputTokenMetric = InferenceModelComponent + "_normalized_time_per_output_token_seconds"
-	RunningRequestsMetric              = InferenceModelComponent + "_running_requests"
+	RequestTotalMetric                 = InferenceObjectiveComponent + "_request_total"
+	RequestErrorTotalMetric            = InferenceObjectiveComponent + "_request_error_total"
+	RequestLatenciesMetric             = InferenceObjectiveComponent + "_request_duration_seconds"
+	RequestSizesMetric                 = InferenceObjectiveComponent + "_request_sizes"
+	ResponseSizesMetric                = InferenceObjectiveComponent + "_response_sizes"
+	InputTokensMetric                  = InferenceObjectiveComponent + "_input_tokens"
+	OutputTokensMetric                 = InferenceObjectiveComponent + "_output_tokens"
+	NormalizedTimePerOutputTokenMetric = InferenceObjectiveComponent + "_normalized_time_per_output_token_seconds"
+	RunningRequestsMetric              = InferenceObjectiveComponent + "_running_requests"
 	KVCacheAvgUsageMetric              = InferencePoolComponent + "_average_kv_cache_utilization"
 	QueueAvgSizeMetric                 = InferencePoolComponent + "_average_queue_size"
 	PerPodQueueSizeMetrics             = InferencePoolComponent + "_per_pod_queue_size"
diff --git a/pkg/epp/metrics/testdata/input_tokens_metric b/pkg/epp/metrics/testdata/input_tokens_metric
index 245c7df..5ec493f 100644
--- a/pkg/epp/metrics/testdata/input_tokens_metric
+++ b/pkg/epp/metrics/testdata/input_tokens_metric
@@ -1,68 +1,68 @@
-# HELP inference_model_input_tokens [ALPHA] Inference model input token count distribution for requests in each model.
-# TYPE inference_model_input_tokens histogram
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="1"} 0
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="8"} 0
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="16"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="32"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="64"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="128"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="256"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="512"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="1024"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="2048"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="4096"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="8192"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="16384"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="32778"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="65536"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="131072"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="262144"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="524288"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="1.048576e+06"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t10",le="+Inf"} 2
-inference_model_input_tokens_sum{model_name="m10",target_model_name="t10"} 30
-inference_model_input_tokens_count{model_name="m10",target_model_name="t10"} 2
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="1"} 0
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="8"} 0
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="16"} 0
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="32"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="64"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="128"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="256"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="512"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="1024"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="2048"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="4096"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="8192"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="16384"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="32778"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="65536"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="131072"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="262144"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="524288"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="1.048576e+06"} 1
-inference_model_input_tokens_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
-inference_model_input_tokens_sum{model_name="m10",target_model_name="t11"} 30
-inference_model_input_tokens_count{model_name="m10",target_model_name="t11"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="1"} 0
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="8"} 0
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="16"} 0
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="32"} 0
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="64"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="128"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="256"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="512"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="1024"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="2048"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="4096"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="8192"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="16384"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="32778"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="65536"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="131072"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="262144"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="524288"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="1.048576e+06"} 1
-inference_model_input_tokens_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
-inference_model_input_tokens_sum{model_name="m20",target_model_name="t20"} 40
-inference_model_input_tokens_count{model_name="m20",target_model_name="t20"} 1
+# HELP inference_objective_input_tokens [ALPHA] Inference objective input token count distribution for requests in each model.
+# TYPE inference_objective_input_tokens histogram
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="1"} 0
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="8"} 0
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="16"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="32"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="64"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="128"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="256"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="512"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="1024"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="2048"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="4096"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="8192"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="16384"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="32778"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="65536"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="131072"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="262144"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="524288"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="1.048576e+06"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t10",le="+Inf"} 2
+inference_objective_input_tokens_sum{model_name="m10",target_model_name="t10"} 30
+inference_objective_input_tokens_count{model_name="m10",target_model_name="t10"} 2
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="1"} 0
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="8"} 0
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="16"} 0
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="32"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="64"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="128"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="256"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="512"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="1024"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="2048"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="4096"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="8192"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="16384"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="32778"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="65536"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="131072"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="262144"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="524288"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="1.048576e+06"} 1
+inference_objective_input_tokens_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
+inference_objective_input_tokens_sum{model_name="m10",target_model_name="t11"} 30
+inference_objective_input_tokens_count{model_name="m10",target_model_name="t11"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="1"} 0
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="8"} 0
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="16"} 0
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="32"} 0
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="64"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="128"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="256"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="512"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="1024"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="2048"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="4096"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="8192"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="16384"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="32778"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="65536"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="131072"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="262144"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="524288"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="1.048576e+06"} 1
+inference_objective_input_tokens_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
+inference_objective_input_tokens_sum{model_name="m20",target_model_name="t20"} 40
+inference_objective_input_tokens_count{model_name="m20",target_model_name="t20"} 1
diff --git a/pkg/epp/metrics/testdata/normalized_time_per_output_token_seconds_metric b/pkg/epp/metrics/testdata/normalized_time_per_output_token_seconds_metric
index bb6e937..0a9c83e 100644
--- a/pkg/epp/metrics/testdata/normalized_time_per_output_token_seconds_metric
+++ b/pkg/epp/metrics/testdata/normalized_time_per_output_token_seconds_metric
@@ -1,50 +1,50 @@
-# HELP inference_model_normalized_time_per_output_token_seconds [ALPHA] Inference model latency divided by number of output tokens in seconds for each model and target model.
-# TYPE inference_model_normalized_time_per_output_token_seconds histogram
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.001"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.002"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.005"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.01"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.02"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.05"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.1"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.2"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.5"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="1.0"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="2.0"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="5.0"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="10.0"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="+Inf"} 2
-inference_model_normalized_time_per_output_token_seconds_sum{model_name="m10", target_model_name="t10"} 0.03
-inference_model_normalized_time_per_output_token_seconds_count{model_name="m10", target_model_name="t10"} 2
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.001"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.002"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.005"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.01"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.02"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.05"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.1"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.2"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.5"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="1.0"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="2.0"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="5.0"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="10.0"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="+Inf"} 1
-inference_model_normalized_time_per_output_token_seconds_sum{model_name="m10", target_model_name="t11"} 0.02
-inference_model_normalized_time_per_output_token_seconds_count{model_name="m10", target_model_name="t11"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.001"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.002"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.005"} 0
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.01"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.02"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.05"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.1"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.2"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.5"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="1.0"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="2.0"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="5.0"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="10.0"} 1
-inference_model_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="+Inf"} 1
-inference_model_normalized_time_per_output_token_seconds_sum{model_name="m20", target_model_name="t20"} 0.006
-inference_model_normalized_time_per_output_token_seconds_count{model_name="m20", target_model_name="t20"} 1
+# HELP inference_objective_normalized_time_per_output_token_seconds [ALPHA] Inference objective latency divided by number of output tokens in seconds for each model and target model.
+# TYPE inference_objective_normalized_time_per_output_token_seconds histogram
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.001"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.002"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.005"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.01"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.02"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.05"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.1"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.2"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="0.5"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="1.0"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="2.0"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="5.0"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="10.0"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t10", le="+Inf"} 2
+inference_objective_normalized_time_per_output_token_seconds_sum{model_name="m10", target_model_name="t10"} 0.03
+inference_objective_normalized_time_per_output_token_seconds_count{model_name="m10", target_model_name="t10"} 2
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.001"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.002"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.005"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.01"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.02"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.05"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.1"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.2"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="0.5"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="1.0"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="2.0"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="5.0"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="10.0"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m10", target_model_name="t11", le="+Inf"} 1
+inference_objective_normalized_time_per_output_token_seconds_sum{model_name="m10", target_model_name="t11"} 0.02
+inference_objective_normalized_time_per_output_token_seconds_count{model_name="m10", target_model_name="t11"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.001"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.002"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.005"} 0
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.01"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.02"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.05"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.1"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.2"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="0.5"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="1.0"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="2.0"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="5.0"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="10.0"} 1
+inference_objective_normalized_time_per_output_token_seconds_bucket{model_name="m20", target_model_name="t20", le="+Inf"} 1
+inference_objective_normalized_time_per_output_token_seconds_sum{model_name="m20", target_model_name="t20"} 0.006
+inference_objective_normalized_time_per_output_token_seconds_count{model_name="m20", target_model_name="t20"} 1
diff --git a/pkg/epp/metrics/testdata/output_tokens_metric b/pkg/epp/metrics/testdata/output_tokens_metric
index 40bbe32..5b71ca0 100644
--- a/pkg/epp/metrics/testdata/output_tokens_metric
+++ b/pkg/epp/metrics/testdata/output_tokens_metric
@@ -1,47 +1,47 @@
-# HELP inference_model_output_tokens [ALPHA] Inference model output token count distribution for requests in each model.
-# TYPE inference_model_output_tokens histogram
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="1"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="8"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="16"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="32"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="64"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="128"} 1
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="256"} 2
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="512"} 2
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="1024"} 2
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="2048"} 2
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="4096"} 2
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="8192"} 2
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t10",le="+Inf"} 2
-inference_model_output_tokens_sum{model_name="m10",target_model_name="t10"} 300
-inference_model_output_tokens_count{model_name="m10",target_model_name="t10"} 2
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="1"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="8"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="16"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="32"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="64"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="128"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="256"} 0
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="512"} 1
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="1024"} 1
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="2048"} 1
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="4096"} 1
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="8192"} 1
-inference_model_output_tokens_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
-inference_model_output_tokens_sum{model_name="m10",target_model_name="t11"} 300
-inference_model_output_tokens_count{model_name="m10",target_model_name="t11"} 1
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="1"} 0
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="8"} 0
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="16"} 0
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="32"} 0
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="64"} 0
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="128"} 0
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="256"} 0
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="512"} 1
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="1024"} 1
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="2048"} 1
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="4096"} 1
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="8192"} 1
-inference_model_output_tokens_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
-inference_model_output_tokens_sum{model_name="m20",target_model_name="t20"} 400
-inference_model_output_tokens_count{model_name="m20",target_model_name="t20"} 1
+# HELP inference_objective_output_tokens [ALPHA] Inference objective output token count distribution for requests in each model.
+# TYPE inference_objective_output_tokens histogram
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="1"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="8"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="16"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="32"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="64"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="128"} 1
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="256"} 2
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="512"} 2
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="1024"} 2
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="2048"} 2
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="4096"} 2
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="8192"} 2
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t10",le="+Inf"} 2
+inference_objective_output_tokens_sum{model_name="m10",target_model_name="t10"} 300
+inference_objective_output_tokens_count{model_name="m10",target_model_name="t10"} 2
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="1"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="8"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="16"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="32"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="64"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="128"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="256"} 0
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="512"} 1
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="1024"} 1
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="2048"} 1
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="4096"} 1
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="8192"} 1
+inference_objective_output_tokens_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
+inference_objective_output_tokens_sum{model_name="m10",target_model_name="t11"} 300
+inference_objective_output_tokens_count{model_name="m10",target_model_name="t11"} 1
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="1"} 0
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="8"} 0
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="16"} 0
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="32"} 0
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="64"} 0
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="128"} 0
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="256"} 0
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="512"} 1
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="1024"} 1
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="2048"} 1
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="4096"} 1
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="8192"} 1
+inference_objective_output_tokens_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
+inference_objective_output_tokens_sum{model_name="m20",target_model_name="t20"} 400
+inference_objective_output_tokens_count{model_name="m20",target_model_name="t20"} 1
diff --git a/pkg/epp/metrics/testdata/request_duration_seconds_metric b/pkg/epp/metrics/testdata/request_duration_seconds_metric
index 6c70b4b..cd6f0c0 100644
--- a/pkg/epp/metrics/testdata/request_duration_seconds_metric
+++ b/pkg/epp/metrics/testdata/request_duration_seconds_metric
@@ -1,116 +1,116 @@
-# HELP inference_model_request_duration_seconds [ALPHA] Inference model response latency distribution in seconds for each model and target model.
-# TYPE inference_model_request_duration_seconds histogram
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.005"} 0
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.025"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.05"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.1"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.2"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.4"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.6"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.8"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1.0"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1.25"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1.5"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="2"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="3"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="4"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="5"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="6"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="8"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="10"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="15"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="20"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="30"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="45"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="60"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="120"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="180"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="240"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="300"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="360"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="480"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="600"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="900"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1200"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1800"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="2700"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="3600"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="Inf"} 2
-inference_model_request_duration_seconds_sum{model_name="m10", target_model_name="t10"} 1.61
-inference_model_request_duration_seconds_count{model_name="m10", target_model_name="t10"} 2
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.005"} 0
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.025"} 0
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.05"} 0
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.1"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.2"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.4"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.6"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.8"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1.25"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1.5"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="2"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="3"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="4"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="5"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="6"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="8"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="10"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="15"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="20"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="30"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="45"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="60"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="120"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="180"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="240"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="300"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="360"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="480"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="600"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="900"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1200"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1800"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="2700"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="3600"} 1
-inference_model_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
-inference_model_request_duration_seconds_sum{model_name="m10",target_model_name="t11"} 0.06
-inference_model_request_duration_seconds_count{model_name="m10",target_model_name="t11"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.005"} 0
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.025"} 0
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.05"} 0
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.1"} 0
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.2"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.4"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.6"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.8"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1.25"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1.5"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="2"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="3"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="4"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="5"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="6"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="8"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="10"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="15"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="20"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="30"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="45"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="60"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="120"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="180"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="240"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="300"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="360"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="480"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="600"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="900"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1200"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1800"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="2700"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="3600"} 1
-inference_model_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
-inference_model_request_duration_seconds_sum{model_name="m20",target_model_name="t20"} 0.12
-inference_model_request_duration_seconds_count{model_name="m20",target_model_name="t20"} 1
+# HELP inference_objective_request_duration_seconds [ALPHA] Inference objective response latency distribution in seconds for each model and target model.
+# TYPE inference_objective_request_duration_seconds histogram
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.005"} 0
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.025"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.05"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.1"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.2"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.4"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.6"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="0.8"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1.0"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1.25"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1.5"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="2"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="3"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="4"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="5"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="6"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="8"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="10"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="15"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="20"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="30"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="45"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="60"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="120"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="180"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="240"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="300"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="360"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="480"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="600"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="900"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1200"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="1800"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="2700"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="3600"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10", target_model_name="t10", le="Inf"} 2
+inference_objective_request_duration_seconds_sum{model_name="m10", target_model_name="t10"} 1.61
+inference_objective_request_duration_seconds_count{model_name="m10", target_model_name="t10"} 2
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.005"} 0
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.025"} 0
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.05"} 0
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.1"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.2"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.4"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.6"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="0.8"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1.25"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1.5"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="2"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="3"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="4"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="5"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="6"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="8"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="10"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="15"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="20"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="30"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="45"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="60"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="120"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="180"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="240"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="300"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="360"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="480"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="600"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="900"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1200"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="1800"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="2700"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="3600"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
+inference_objective_request_duration_seconds_sum{model_name="m10",target_model_name="t11"} 0.06
+inference_objective_request_duration_seconds_count{model_name="m10",target_model_name="t11"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.005"} 0
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.025"} 0
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.05"} 0
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.1"} 0
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.2"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.4"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.6"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="0.8"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1.25"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1.5"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="2"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="3"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="4"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="5"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="6"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="8"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="10"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="15"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="20"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="30"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="45"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="60"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="120"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="180"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="240"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="300"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="360"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="480"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="600"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="900"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1200"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="1800"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="2700"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="3600"} 1
+inference_objective_request_duration_seconds_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
+inference_objective_request_duration_seconds_sum{model_name="m20",target_model_name="t20"} 0.12
+inference_objective_request_duration_seconds_count{model_name="m20",target_model_name="t20"} 1
diff --git a/pkg/epp/metrics/testdata/request_error_total_metric b/pkg/epp/metrics/testdata/request_error_total_metric
index 31036eb..2a2e553 100644
--- a/pkg/epp/metrics/testdata/request_error_total_metric
+++ b/pkg/epp/metrics/testdata/request_error_total_metric
@@ -1,5 +1,5 @@
-# HELP inference_model_request_error_total [ALPHA] Counter of inference model requests errors broken out for each model and target model.
-# TYPE inference_model_request_error_total counter
-inference_model_request_error_total{error_code="Internal", model_name="m10",target_model_name="t10"} 2
-inference_model_request_error_total{error_code="ModelServerError", model_name="m10",target_model_name="t11"} 1
-inference_model_request_error_total{error_code="InferencePoolResourceExhausted", model_name="m20",target_model_name="t20"} 1
+# HELP inference_objective_request_error_total [ALPHA] Counter of inference objective requests errors broken out for each model and target model.
+# TYPE inference_objective_request_error_total counter
+inference_objective_request_error_total{error_code="Internal", model_name="m10",target_model_name="t10"} 2
+inference_objective_request_error_total{error_code="ModelServerError", model_name="m10",target_model_name="t11"} 1
+inference_objective_request_error_total{error_code="InferencePoolResourceExhausted", model_name="m20",target_model_name="t20"} 1
diff --git a/pkg/epp/metrics/testdata/request_sizes_metric b/pkg/epp/metrics/testdata/request_sizes_metric
index ceca532..74e6725 100644
--- a/pkg/epp/metrics/testdata/request_sizes_metric
+++ b/pkg/epp/metrics/testdata/request_sizes_metric
@@ -1,86 +1,86 @@
-# HELP inference_model_request_sizes [ALPHA] Inference model requests size distribution in bytes for each model and target model.
-# TYPE inference_model_request_sizes histogram
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="64"} 0
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="128"} 0
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="256"} 0
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="512"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1024"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="2048"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="4096"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="8192"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="16384"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="32768"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="65536"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="131072"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="262144"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="524288"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1.048576e+06"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="2.097152e+06"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="4.194304e+06"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="8.388608e+06"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1.6777216e+07"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="3.3554432e+07"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="6.7108864e+07"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1.34217728e+08"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="2.68435456e+08"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="5.36870912e+08"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1.073741824e+09"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t10",le="+Inf"} 2
-inference_model_request_sizes_sum{model_name="m10",target_model_name="t10"} 1700
-inference_model_request_sizes_count{model_name="m10",target_model_name="t10"} 2
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="64"} 0
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="128"} 0
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="256"} 0
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="512"} 0
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1024"} 0
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="2048"} 0
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="4096"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="8192"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="16384"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="32768"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="65536"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="131072"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="262144"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="524288"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1.048576e+06"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="2.097152e+06"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="4.194304e+06"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="8.388608e+06"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1.6777216e+07"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="3.3554432e+07"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="6.7108864e+07"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1.34217728e+08"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="2.68435456e+08"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="5.36870912e+08"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1.073741824e+09"} 1
-inference_model_request_sizes_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
-inference_model_request_sizes_sum{model_name="m10",target_model_name="t11"} 2480
-inference_model_request_sizes_count{model_name="m10",target_model_name="t11"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="64"} 0
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="128"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="256"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="512"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1024"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="2048"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="4096"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="8192"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="16384"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="32768"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="65536"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="131072"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="262144"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="524288"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1.048576e+06"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="2.097152e+06"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="4.194304e+06"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="8.388608e+06"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1.6777216e+07"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="3.3554432e+07"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="6.7108864e+07"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1.34217728e+08"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="2.68435456e+08"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="5.36870912e+08"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1.073741824e+09"} 1
-inference_model_request_sizes_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
-inference_model_request_sizes_sum{model_name="m20",target_model_name="t20"} 80
-inference_model_request_sizes_count{model_name="m20",target_model_name="t20"} 1
+# HELP inference_objective_request_sizes [ALPHA] Inference objective requests size distribution in bytes for each model and target model.
+# TYPE inference_objective_request_sizes histogram
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="64"} 0
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="128"} 0
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="256"} 0
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="512"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1024"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="2048"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="4096"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="8192"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="16384"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="32768"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="65536"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="131072"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="262144"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="524288"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1.048576e+06"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="2.097152e+06"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="4.194304e+06"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="8.388608e+06"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1.6777216e+07"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="3.3554432e+07"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="6.7108864e+07"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1.34217728e+08"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="2.68435456e+08"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="5.36870912e+08"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="1.073741824e+09"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t10",le="+Inf"} 2
+inference_objective_request_sizes_sum{model_name="m10",target_model_name="t10"} 1700
+inference_objective_request_sizes_count{model_name="m10",target_model_name="t10"} 2
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="64"} 0
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="128"} 0
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="256"} 0
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="512"} 0
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1024"} 0
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="2048"} 0
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="4096"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="8192"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="16384"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="32768"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="65536"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="131072"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="262144"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="524288"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1.048576e+06"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="2.097152e+06"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="4.194304e+06"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="8.388608e+06"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1.6777216e+07"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="3.3554432e+07"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="6.7108864e+07"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1.34217728e+08"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="2.68435456e+08"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="5.36870912e+08"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="1.073741824e+09"} 1
+inference_objective_request_sizes_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
+inference_objective_request_sizes_sum{model_name="m10",target_model_name="t11"} 2480
+inference_objective_request_sizes_count{model_name="m10",target_model_name="t11"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="64"} 0
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="128"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="256"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="512"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1024"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="2048"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="4096"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="8192"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="16384"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="32768"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="65536"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="131072"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="262144"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="524288"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1.048576e+06"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="2.097152e+06"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="4.194304e+06"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="8.388608e+06"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1.6777216e+07"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="3.3554432e+07"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="6.7108864e+07"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1.34217728e+08"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="2.68435456e+08"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="5.36870912e+08"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="1.073741824e+09"} 1
+inference_objective_request_sizes_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
+inference_objective_request_sizes_sum{model_name="m20",target_model_name="t20"} 80
+inference_objective_request_sizes_count{model_name="m20",target_model_name="t20"} 1
diff --git a/pkg/epp/metrics/testdata/request_total_metric b/pkg/epp/metrics/testdata/request_total_metric
index 9c6f48a..a6200fd 100644
--- a/pkg/epp/metrics/testdata/request_total_metric
+++ b/pkg/epp/metrics/testdata/request_total_metric
@@ -1,5 +1,5 @@
-# HELP inference_model_request_total [ALPHA] Counter of inference model requests broken out for each model and target model.
-# TYPE inference_model_request_total counter
-inference_model_request_total{model_name="m10", target_model_name="t10"} 2
-inference_model_request_total{model_name="m10", target_model_name="t11"} 1
-inference_model_request_total{model_name="m20", target_model_name="t20"} 1
+# HELP inference_objective_request_total [ALPHA] Counter of inference objective requests broken out for each model and target model.
+# TYPE inference_objective_request_total counter
+inference_objective_request_total{model_name="m10", target_model_name="t10"} 2
+inference_objective_request_total{model_name="m10", target_model_name="t11"} 1
+inference_objective_request_total{model_name="m20", target_model_name="t20"} 1
diff --git a/pkg/epp/metrics/testdata/response_sizes_metric b/pkg/epp/metrics/testdata/response_sizes_metric
index 7f98109..a9ad76e 100644
--- a/pkg/epp/metrics/testdata/response_sizes_metric
+++ b/pkg/epp/metrics/testdata/response_sizes_metric
@@ -1,56 +1,56 @@
-# HELP inference_model_response_sizes [ALPHA] Inference model responses size distribution in bytes for each model and target model.
-# TYPE inference_model_response_sizes histogram
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="1"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="8"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="16"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="32"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="64"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="128"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="256"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="512"} 1
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="1024"} 1
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="2048"} 2
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="4096"} 2
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="8192"} 2
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="16384"} 2
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="32778"} 2
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="65536"} 2
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t10",le="+Inf"} 2
-inference_model_response_sizes_sum{model_name="m10",target_model_name="t10"} 1700
-inference_model_response_sizes_count{model_name="m10",target_model_name="t10"} 2
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="1"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="8"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="16"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="32"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="64"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="128"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="256"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="512"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="1024"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="2048"} 0
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="4096"} 1
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="8192"} 1
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="16384"} 1
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="32778"} 1
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="65536"} 1
-inference_model_response_sizes_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
-inference_model_response_sizes_sum{model_name="m10",target_model_name="t11"} 2480
-inference_model_response_sizes_count{model_name="m10",target_model_name="t11"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="1"} 0
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="8"} 0
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="16"} 0
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="32"} 0
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="64"} 0
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="128"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="256"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="512"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="1024"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="2048"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="4096"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="8192"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="16384"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="32778"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="65536"} 1
-inference_model_response_sizes_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
-inference_model_response_sizes_sum{model_name="m20",target_model_name="t20"} 80
-inference_model_response_sizes_count{model_name="m20",target_model_name="t20"} 1
+# HELP inference_objective_response_sizes [ALPHA] Inference objective responses size distribution in bytes for each model and target model.
+# TYPE inference_objective_response_sizes histogram
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="1"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="8"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="16"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="32"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="64"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="128"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="256"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="512"} 1
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="1024"} 1
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="2048"} 2
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="4096"} 2
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="8192"} 2
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="16384"} 2
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="32778"} 2
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="65536"} 2
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t10",le="+Inf"} 2
+inference_objective_response_sizes_sum{model_name="m10",target_model_name="t10"} 1700
+inference_objective_response_sizes_count{model_name="m10",target_model_name="t10"} 2
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="1"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="8"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="16"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="32"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="64"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="128"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="256"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="512"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="1024"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="2048"} 0
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="4096"} 1
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="8192"} 1
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="16384"} 1
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="32778"} 1
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="65536"} 1
+inference_objective_response_sizes_bucket{model_name="m10",target_model_name="t11",le="+Inf"} 1
+inference_objective_response_sizes_sum{model_name="m10",target_model_name="t11"} 2480
+inference_objective_response_sizes_count{model_name="m10",target_model_name="t11"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="1"} 0
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="8"} 0
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="16"} 0
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="32"} 0
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="64"} 0
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="128"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="256"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="512"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="1024"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="2048"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="4096"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="8192"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="16384"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="32778"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="65536"} 1
+inference_objective_response_sizes_bucket{model_name="m20",target_model_name="t20",le="+Inf"} 1
+inference_objective_response_sizes_sum{model_name="m20",target_model_name="t20"} 80
+inference_objective_response_sizes_count{model_name="m20",target_model_name="t20"} 1
diff --git a/pkg/epp/metrics/testdata/running_requests_metrics b/pkg/epp/metrics/testdata/running_requests_metrics
index a880e49..962a50f 100644
--- a/pkg/epp/metrics/testdata/running_requests_metrics
+++ b/pkg/epp/metrics/testdata/running_requests_metrics
@@ -1,4 +1,4 @@
-# HELP inference_model_running_requests [ALPHA] Inference model number of running requests in each model.
-# TYPE inference_model_running_requests gauge
-inference_model_running_requests{model_name="m1"} 1
-inference_model_running_requests{model_name="m2"} 1
+# HELP inference_objective_running_requests [ALPHA] Inference objective number of running requests in each model.
+# TYPE inference_objective_running_requests gauge
+inference_objective_running_requests{model_name="m1"} 1
+inference_objective_running_requests{model_name="m2"} 1
diff --git a/pkg/epp/plugins/plugin_state_test.go b/pkg/epp/plugins/plugin_state_test.go
index 46c0de8..0de65c2 100644
--- a/pkg/epp/plugins/plugin_state_test.go
+++ b/pkg/epp/plugins/plugin_state_test.go
@@ -66,8 +66,14 @@ func TestPluginState_ReadWrite(t *testing.T) {
 	assert.True(t, ok, "should be able to cast to pluginTestData")
 	assert.Equal(t, data1, td.value)
 
-	// Delete the req2 data and verify it's removed
+	// Delete the req2 data and verify content that was read before is still valid
+	readData, err = state.Read(req2, key)
+	assert.NoError(t, err)
 	state.Delete(req2)
+	td, ok = readData.(*pluginTestData)
+	assert.True(t, ok, "should be able to cast to pluginTestData")
+	assert.Equal(t, data2, td.value)
+	// try to read again aftet deletion, verify error
 	readData, err = state.Read(req2, key)
 	assert.Equal(t, ErrNotFound, err)
 	assert.Nil(t, readData, "expected no data after delete")
diff --git a/pkg/epp/requestcontrol/director_test.go b/pkg/epp/requestcontrol/director_test.go
index e7968d4..a0cb7c3 100644
--- a/pkg/epp/requestcontrol/director_test.go
+++ b/pkg/epp/requestcontrol/director_test.go
@@ -34,6 +34,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
 	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+	"sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend"
 	backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datastore"
@@ -53,7 +54,7 @@ type mockSaturationDetector struct {
 	isSaturated bool
 }
 
-func (m *mockSaturationDetector) IsSaturated(_ context.Context) bool {
+func (m *mockSaturationDetector) IsSaturated(_ context.Context, _ []backendmetrics.PodMetrics) bool {
 	return m.isSaturated
 }
 
@@ -66,6 +67,23 @@ func (m *mockScheduler) Schedule(_ context.Context, _ *schedulingtypes.LLMReques
 	return m.scheduleResults, m.scheduleErr
 }
 
+type mockDatastore struct {
+	pods []backendmetrics.PodMetrics
+}
+
+func (ds *mockDatastore) PoolGet() (*v1.InferencePool, error)                { return nil, nil }
+func (ds *mockDatastore) ObjectiveGet(_ string) *v1alpha2.InferenceObjective { return nil }
+func (ds *mockDatastore) PodList(predicate func(backendmetrics.PodMetrics) bool) []backendmetrics.PodMetrics {
+	res := []backendmetrics.PodMetrics{}
+	for _, pod := range ds.pods {
+		if predicate(pod) {
+			res = append(res, pod)
+		}
+	}
+
+	return res
+}
+
 func TestDirector_HandleRequest(t *testing.T) {
 	ctx := logutil.NewTestLoggerIntoContext(context.Background())
 
@@ -450,119 +468,72 @@ func TestGetCandidatePodsForScheduling(t *testing.T) {
 		}
 	}
 
-	testInput := []*corev1.Pod{
-		{
-			ObjectMeta: metav1.ObjectMeta{
-				Name: "pod1",
-			},
-			Status: corev1.PodStatus{
-				PodIP: "10.0.0.1",
-			},
-		},
-		{
-			ObjectMeta: metav1.ObjectMeta{
-				Name: "pod2",
-			},
-			Status: corev1.PodStatus{
-				PodIP: "10.0.0.2",
-			},
-		},
-	}
-
-	outputPod1 := &backend.Pod{
+	pod1 := &backend.Pod{
 		NamespacedName: types.NamespacedName{Name: "pod1"},
 		Address:        "10.0.0.1",
 		Labels:         map[string]string{},
 	}
 
-	outputPod2 := &backend.Pod{
+	pod2 := &backend.Pod{
 		NamespacedName: types.NamespacedName{Name: "pod2"},
 		Address:        "10.0.0.2",
 		Labels:         map[string]string{},
 	}
 
+	testInput := []backendmetrics.PodMetrics{
+		&backendmetrics.FakePodMetrics{Pod: pod1},
+		&backendmetrics.FakePodMetrics{Pod: pod2},
+	}
+
 	tests := []struct {
 		name     string
 		metadata map[string]any
-		output   []schedulingtypes.Pod
+		output   []backendmetrics.PodMetrics
 	}{
 		{
 			name:     "SubsetFilter, filter not present — return all pods",
 			metadata: map[string]any{},
-			output: []schedulingtypes.Pod{
-				&schedulingtypes.PodMetrics{
-					Pod:          outputPod1,
-					MetricsState: backendmetrics.NewMetricsState(),
-				},
-				&schedulingtypes.PodMetrics{
-					Pod:          outputPod2,
-					MetricsState: backendmetrics.NewMetricsState(),
-				},
-			},
+			output:   testInput,
 		},
 		{
 			name:     "SubsetFilter, namespace present filter not present — return all pods",
 			metadata: map[string]any{metadata.SubsetFilterNamespace: map[string]any{}},
-			output: []schedulingtypes.Pod{
-				&schedulingtypes.PodMetrics{
-					Pod:          outputPod1,
-					MetricsState: backendmetrics.NewMetricsState(),
-				},
-				&schedulingtypes.PodMetrics{
-					Pod:          outputPod2,
-					MetricsState: backendmetrics.NewMetricsState(),
-				},
-			},
+			output:   testInput,
 		},
 		{
 			name:     "SubsetFilter, filter present with empty list — return error",
 			metadata: makeFilterMetadata([]any{}),
-			output:   []schedulingtypes.Pod{},
+			output:   []backendmetrics.PodMetrics{},
 		},
 		{
 			name:     "SubsetFilter, subset with one matching pod",
 			metadata: makeFilterMetadata([]any{"10.0.0.1"}),
-			output: []schedulingtypes.Pod{
-				&schedulingtypes.PodMetrics{
-					Pod:          outputPod1,
-					MetricsState: backendmetrics.NewMetricsState(),
+			output: []backendmetrics.PodMetrics{
+				&backendmetrics.FakePodMetrics{
+					Pod: pod1,
 				},
 			},
 		},
 		{
 			name:     "SubsetFilter, subset with multiple matching pods",
 			metadata: makeFilterMetadata([]any{"10.0.0.1", "10.0.0.2", "10.0.0.3"}),
-			output: []schedulingtypes.Pod{
-				&schedulingtypes.PodMetrics{
-					Pod:          outputPod1,
-					MetricsState: backendmetrics.NewMetricsState(),
-				},
-				&schedulingtypes.PodMetrics{
-					Pod:          outputPod2,
-					MetricsState: backendmetrics.NewMetricsState(),
-				},
-			},
+			output:   testInput,
 		},
 		{
 			name:     "SubsetFilter, subset with no matching pods",
 			metadata: makeFilterMetadata([]any{"10.0.0.3"}),
-			output:   []schedulingtypes.Pod{},
+			output:   []backendmetrics.PodMetrics{},
 		},
 	}
 
-	pmf := backendmetrics.NewPodMetricsFactory(&backendmetrics.FakePodMetricsClient{}, time.Second)
-	ds := datastore.NewDatastore(t.Context(), pmf)
-	for _, testPod := range testInput {
-		ds.PodUpdateOrAddIfNotExist(testPod)
-	}
-
+	ds := &mockDatastore{pods: testInput}
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
 			director := NewDirectorWithConfig(ds, &mockScheduler{}, &mockSaturationDetector{}, NewConfig())
 
 			got := director.getCandidatePodsForScheduling(context.Background(), test.metadata)
 
-			diff := cmp.Diff(test.output, got, cmpopts.SortSlices(func(a, b schedulingtypes.Pod) bool {
+			diff := cmp.Diff(test.output, got, cmpopts.SortSlices(func(a, b backendmetrics.PodMetrics) bool {
 				return a.GetPod().NamespacedName.String() < b.GetPod().NamespacedName.String()
 			}))
 			if diff != "" {
diff --git a/pkg/epp/saturationdetector/saturationdetector_test.go b/pkg/epp/saturationdetector/saturationdetector_test.go
index f2530bd..0b861d9 100644
--- a/pkg/epp/saturationdetector/saturationdetector_test.go
+++ b/pkg/epp/saturationdetector/saturationdetector_test.go
@@ -25,27 +25,13 @@ import (
 	"time"
 
 	"github.com/go-logr/logr"
+	"github.com/google/go-cmp/cmp"
 	"k8s.io/apimachinery/pkg/types"
 
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend"
 	backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
 )
 
-// --- Mock Implementations ---
-
-type mockDatastore struct {
-	pods []*backendmetrics.FakePodMetrics
-}
-
-// PodList lists pods matching the given predicate.
-func (fds *mockDatastore) PodList(predicate func(backendmetrics.PodMetrics) bool) []backendmetrics.PodMetrics {
-	pm := make([]backendmetrics.PodMetrics, 0, len(fds.pods))
-	for _, pod := range fds.pods {
-		pm = append(pm, pod)
-	}
-	return pm
-}
-
 func newMockPodMetrics(name string, metrics *backendmetrics.MetricsState) *backendmetrics.FakePodMetrics {
 	return &backendmetrics.FakePodMetrics{
 		Pod: &backend.Pod{
@@ -59,12 +45,9 @@ func newMockPodMetrics(name string, metrics *backendmetrics.MetricsState) *backe
 
 func TestNewDetector(t *testing.T) {
 	tests := []struct {
-		name                         string
-		config                       *Config
-		datastore                    Datastore
-		expectedQueueDepthThreshold  int
-		expectedKVCacheUtilThreshold float64
-		expectedStalenessThreshold   time.Duration
+		name           string
+		config         *Config
+		expectedConfig *Config
 	}{
 		{
 			name: "Valid config",
@@ -73,10 +56,11 @@ func TestNewDetector(t *testing.T) {
 				KVCacheUtilThreshold:      0.8,
 				MetricsStalenessThreshold: 100 * time.Millisecond,
 			},
-			datastore:                    &mockDatastore{},
-			expectedQueueDepthThreshold:  10,
-			expectedKVCacheUtilThreshold: 0.8,
-			expectedStalenessThreshold:   100 * time.Millisecond,
+			expectedConfig: &Config{
+				QueueDepthThreshold:       10,
+				KVCacheUtilThreshold:      0.8,
+				MetricsStalenessThreshold: 100 * time.Millisecond,
+			},
 		},
 		{
 			name: "invalid thresholds, fallback to default",
@@ -85,10 +69,11 @@ func TestNewDetector(t *testing.T) {
 				KVCacheUtilThreshold:      -5,
 				MetricsStalenessThreshold: 0,
 			},
-			datastore:                    &mockDatastore{},
-			expectedQueueDepthThreshold:  DefaultQueueDepthThreshold,
-			expectedKVCacheUtilThreshold: DefaultKVCacheUtilThreshold,
-			expectedStalenessThreshold:   DefaultMetricsStalenessThreshold,
+			expectedConfig: &Config{
+				QueueDepthThreshold:       DefaultQueueDepthThreshold,
+				KVCacheUtilThreshold:      DefaultKVCacheUtilThreshold,
+				MetricsStalenessThreshold: DefaultMetricsStalenessThreshold,
+			},
 		},
 		{
 			name: "kv cache threshold above range, fallback to default",
@@ -97,10 +82,11 @@ func TestNewDetector(t *testing.T) {
 				KVCacheUtilThreshold:      1.5,
 				MetricsStalenessThreshold: 100 * time.Millisecond,
 			},
-			datastore:                    &mockDatastore{},
-			expectedQueueDepthThreshold:  10,
-			expectedKVCacheUtilThreshold: DefaultKVCacheUtilThreshold,
-			expectedStalenessThreshold:   100 * time.Millisecond,
+			expectedConfig: &Config{
+				QueueDepthThreshold:       10,
+				KVCacheUtilThreshold:      DefaultKVCacheUtilThreshold,
+				MetricsStalenessThreshold: 100 * time.Millisecond,
+			},
 		},
 	}
 
@@ -111,19 +97,9 @@ func TestNewDetector(t *testing.T) {
 			os.Setenv(EnvSdKVCacheUtilThreshold, fmt.Sprintf("%v", test.config.KVCacheUtilThreshold))
 			os.Setenv(EnvSdMetricsStalenessThreshold, test.config.MetricsStalenessThreshold.String())
 
-			detector := NewDetector(LoadConfigFromEnv(), test.datastore, logr.Discard())
-			if detector == nil {
-				t.Fatalf("NewDetector() returned nil detector for valid config")
-				return // explicit return so staticcheck does not warn on potential nil detector below.
-			}
-			if detector.config.QueueDepthThreshold != test.expectedQueueDepthThreshold {
-				t.Errorf("NewDetector() QueueDepthThreshold = %d, want %d", detector.config.QueueDepthThreshold, test.expectedQueueDepthThreshold)
-			}
-			if detector.config.KVCacheUtilThreshold != test.expectedKVCacheUtilThreshold {
-				t.Errorf("NewDetector() KVCacheUtilThreshold = %f, want %f", detector.config.KVCacheUtilThreshold, test.expectedKVCacheUtilThreshold)
-			}
-			if detector.config.MetricsStalenessThreshold != test.expectedStalenessThreshold {
-				t.Errorf("NewDetector() MetricsStalenessThreshold = %v, want %v", detector.config.MetricsStalenessThreshold, test.expectedStalenessThreshold)
+			detector := NewDetector(LoadConfigFromEnv(), logr.Discard())
+			if diff := cmp.Diff(test.expectedConfig, detector.config); diff != "" {
+				t.Errorf("Unexpected output (-want +got): %v", diff)
 			}
 		})
 	}
@@ -138,77 +114,77 @@ func TestDetector_IsSaturated(t *testing.T) {
 	}
 
 	tests := []struct {
-		name            string
-		config          *Config
-		pods            []*backendmetrics.FakePodMetrics
-		expectedSaturat bool
+		name               string
+		config             *Config
+		pods               []backendmetrics.PodMetrics
+		expectedSaturation bool
 	}{
 		{
-			name:            "No pods in datastore",
-			config:          defaultConfig,
-			pods:            []*backendmetrics.FakePodMetrics{},
-			expectedSaturat: true, // No capacity = saturated
+			name:               "No candidate pods",
+			config:             defaultConfig,
+			pods:               []backendmetrics.PodMetrics{},
+			expectedSaturation: true, // No capacity = saturated
 		},
 		{
 			name:   "Single pod with good capacity",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime,
 					WaitingQueueSize:    2,
 					KVCacheUsagePercent: 0.5,
 				}),
 			},
-			expectedSaturat: false,
+			expectedSaturation: false,
 		},
 		{
 			name:   "Single pod with stale metrics",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime.Add(-200 * time.Millisecond), // Stale
 					WaitingQueueSize:    1,
 					KVCacheUsagePercent: 0.1,
 				}),
 			},
-			expectedSaturat: true,
+			expectedSaturation: true,
 		},
 		{
 			name:   "Single pod with high queue depth",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime,
 					WaitingQueueSize:    10, // Exceeds threshold 5
 					KVCacheUsagePercent: 0.1,
 				}),
 			},
-			expectedSaturat: true,
+			expectedSaturation: true,
 		},
 		{
 			name:   "Single pod with high KV cache utilization",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime,
 					WaitingQueueSize:    1,
 					KVCacheUsagePercent: 0.95, // Exceeds threshold 0.90
 				}),
 			},
-			expectedSaturat: true,
+			expectedSaturation: true,
 		},
 		{
 			name:   "Single pod with nil metrics",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", nil),
 			},
-			expectedSaturat: true,
+			expectedSaturation: true,
 		},
 		{
 			name:   "Multiple pods, all good capacity",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime,
 					WaitingQueueSize:    1,
@@ -220,12 +196,12 @@ func TestDetector_IsSaturated(t *testing.T) {
 					KVCacheUsagePercent: 0.2,
 				}),
 			},
-			expectedSaturat: false,
+			expectedSaturation: false,
 		},
 		{
 			name:   "Multiple pods, one good, one bad (stale)",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime, // Good
 					WaitingQueueSize:    1,
@@ -237,12 +213,12 @@ func TestDetector_IsSaturated(t *testing.T) {
 					KVCacheUsagePercent: 0.2,
 				}),
 			},
-			expectedSaturat: false, // One good pod is enough
+			expectedSaturation: false, // One good pod is enough
 		},
 		{
 			name:   "Multiple pods, one good, one bad (high queue)",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime,
 					WaitingQueueSize:    1,
@@ -254,12 +230,12 @@ func TestDetector_IsSaturated(t *testing.T) {
 					KVCacheUsagePercent: 0.2,
 				}),
 			},
-			expectedSaturat: false,
+			expectedSaturation: false,
 		},
 		{
 			name:   "Multiple pods, all bad capacity",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime.Add(-200 * time.Millisecond), // Stale
 					WaitingQueueSize:    1,
@@ -276,52 +252,52 @@ func TestDetector_IsSaturated(t *testing.T) {
 					KVCacheUsagePercent: 0.99, // High KV
 				}),
 			},
-			expectedSaturat: true,
+			expectedSaturation: true,
 		},
 		{
 			name:   "Queue depth exactly at threshold",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime,
 					WaitingQueueSize:    defaultConfig.QueueDepthThreshold, // Exactly at threshold (good)
 					KVCacheUsagePercent: 0.1,
 				}),
 			},
-			expectedSaturat: false,
+			expectedSaturation: false,
 		},
 		{
 			name:   "KV cache exactly at threshold",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime,
 					WaitingQueueSize:    1,
 					KVCacheUsagePercent: defaultConfig.KVCacheUtilThreshold, // Exactly at threshold (good)
 				}),
 			},
-			expectedSaturat: false,
+			expectedSaturation: false,
 		},
 		{
 			name:   "Metrics age just over staleness threshold",
 			config: defaultConfig,
-			pods: []*backendmetrics.FakePodMetrics{
+			pods: []backendmetrics.PodMetrics{
 				newMockPodMetrics("pod1", &backendmetrics.MetricsState{
 					UpdateTime:          baseTime.Add(-defaultConfig.MetricsStalenessThreshold - time.Nanosecond), // Just over (stale)
 					WaitingQueueSize:    1,
 					KVCacheUsagePercent: 0.1,
 				}),
 			},
-			expectedSaturat: true,
+			expectedSaturation: true,
 		},
 	}
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			detector := NewDetector(test.config, &mockDatastore{pods: test.pods}, logr.Discard())
+			detector := NewDetector(test.config, logr.Discard())
 
-			if got := detector.IsSaturated(context.Background()); got != test.expectedSaturat {
-				t.Errorf("IsSaturated() = %v, want %v", got, test.expectedSaturat)
+			if got := detector.IsSaturated(context.Background(), test.pods); got != test.expectedSaturation {
+				t.Errorf("IsSaturated() = %v, want %v", got, test.expectedSaturation)
 			}
 		})
 	}
diff --git a/pkg/epp/scheduling/framework/plugins/multi/prefix/indexer_test.go b/pkg/epp/scheduling/framework/plugins/multi/prefix/indexer_test.go
index a151121..6d4fcc5 100644
--- a/pkg/epp/scheduling/framework/plugins/multi/prefix/indexer_test.go
+++ b/pkg/epp/scheduling/framework/plugins/multi/prefix/indexer_test.go
@@ -16,13 +16,14 @@ limitations under the License.
 package prefix
 
 import (
+	"context"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
 )
 
 func TestIndexer_AddAndGet(t *testing.T) {
-	i := newIndexer(2)
+	i := newIndexer(context.Background(), 2)
 
 	hash1 := BlockHash(1)
 	server := ServerID{Namespace: "default", Name: "server1"}
diff --git a/pkg/epp/scheduling/framework/plugins/multi/prefix/plugin_test.go b/pkg/epp/scheduling/framework/plugins/multi/prefix/plugin_test.go
index aaf68f0..54a00ab 100644
--- a/pkg/epp/scheduling/framework/plugins/multi/prefix/plugin_test.go
+++ b/pkg/epp/scheduling/framework/plugins/multi/prefix/plugin_test.go
@@ -24,21 +24,22 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/google/uuid"
 	"github.com/stretchr/testify/assert"
 	k8stypes "k8s.io/apimachinery/pkg/types"
 
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/plugins"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
 )
 
-func TestPrefixPlugin(t *testing.T) {
-
+func TestPrefixPluginCompletion(t *testing.T) {
 	config := Config{
-		HashBlockSize:          4,
+		BlockSize:              4,
 		MaxPrefixBlocksToMatch: DefaultMaxPrefixBlocks,
 		LRUCapacityPerServer:   DefaultLRUCapacityPerServer,
 	}
-	plugin := New(config)
+	plugin := New(context.Background(), config)
 
 	pod1 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}}
 	pod2 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod2"}}}
@@ -46,101 +47,301 @@ func TestPrefixPlugin(t *testing.T) {
 
 	// First request.
 	req1 := &types.LLMRequest{
+		RequestId:   uuid.NewString(),
 		TargetModel: "test-model1",
-		Prompt:      "aaaaaa",
+		Body: &types.LLMRequestBody{
+			Completions: &types.CompletionsRequest{
+				Prompt: "aaaaaa",
+			},
+		},
 	}
-	cycleState1 := types.NewCycleState()
-	scores := plugin.Score(context.Background(), cycleState1, req1, pods)
-	state, err := types.ReadCycleStateKey[*SchedulingContextState](cycleState1, PrefixCachePluginType)
+	scores := plugin.Score(context.Background(), types.NewCycleState(), req1, pods)
+	state, err := plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req1.RequestId, plugins.StateKey(plugin.TypedName().String()))
 	assert.NoError(t, err)
 	t.Logf("Hashes %+v, cached servers: %+v", state.PrefixHashes, state.PrefixCacheServers)
 	// Input size is 6, hash block size is 4, the last 2 characters are ignored.
-	// Total hashes = 2 (the first one is for the model)
-	assert.Equal(t, 2, len(state.PrefixHashes), "number of hashes is incorrect")
+	// Total hashes = 1 (the first one is for the prefix with model)
+	assert.Equal(t, 1, len(state.PrefixHashes), "number of hashes is incorrect")
 	assert.Equal(t, 0, len(state.PrefixCacheServers), "there shouldn't be any cached servers")
 	assert.Equal(t, float64(0), scores[pod1], "score for pod1")
 	assert.Equal(t, float64(0), scores[pod2], "score for pod2")
 
 	// Simulate pod1 was picked.
-	plugin.PostCycle(context.Background(), cycleState1, &types.ProfileRunResult{TargetPods: []types.Pod{pod1}})
+	schedulingResult := &types.SchedulingResult{
+		PrimaryProfileName: "default",
+		ProfileResults: map[string]*types.ProfileRunResult{
+			"default": {TargetPods: []types.Pod{pod1}},
+		},
+	}
+	plugin.PreRequest(context.Background(), req1, schedulingResult, 0)
+	plugin.wg.Wait()
 
 	// Second request doesn't share any prefix with first one. It should be added to the cache but
 	// the pod score should be 0.
 	req2 := &types.LLMRequest{
+		RequestId:   uuid.NewString(),
 		TargetModel: "test-model2",
-		Prompt:      "bbbbbb",
+		Body: &types.LLMRequestBody{
+			Completions: &types.CompletionsRequest{
+				Prompt: "bbbbbb",
+			},
+		},
 	}
-	cycleState2 := types.NewCycleState()
-	scores = plugin.Score(context.Background(), cycleState2, req2, pods)
-	state, err = types.ReadCycleStateKey[*SchedulingContextState](cycleState2, PrefixCachePluginType)
+	scores = plugin.Score(context.Background(), types.NewCycleState(), req2, pods)
+	state, err = plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req2.RequestId, plugins.StateKey(plugin.TypedName().String()))
 	assert.NoError(t, err)
 	t.Logf("Hashes %+v, cached servers: %+v", state.PrefixHashes, state.PrefixCacheServers)
 	// Input size is 6, hash block size is 4, the last 2 characters are ignored.
-	// Total hashes = 2 (the first one is for the model)
-	assert.Equal(t, 2, len(state.PrefixHashes), "number of hashes is incorrect")
+	// Total hashes = 1 (the first one is for the prefix with model)
+	assert.Equal(t, 1, len(state.PrefixHashes), "number of hashes is incorrect")
 	assert.Equal(t, 0, len(state.PrefixCacheServers), "there shouldn't be any cached servers")
 	assert.Equal(t, float64(0), scores[pod1], "score for pod1")
 	assert.Equal(t, float64(0), scores[pod2], "score for pod2")
 
 	// Simulate pod2 was picked.
-	plugin.PostCycle(context.Background(), cycleState2, &types.ProfileRunResult{TargetPods: []types.Pod{pod2}})
+	schedulingResult = &types.SchedulingResult{
+		PrimaryProfileName: "default",
+		ProfileResults: map[string]*types.ProfileRunResult{
+			"default": {TargetPods: []types.Pod{pod2}},
+		},
+	}
+	plugin.PreRequest(context.Background(), req2, schedulingResult, 0)
+	plugin.wg.Wait()
 
 	// Third request shares partial prefix with first one.
 	req3 := &types.LLMRequest{
+		RequestId:   uuid.NewString(),
 		TargetModel: "test-model1",
-		Prompt:      "aaaabbbb",
+		Body: &types.LLMRequestBody{
+			Completions: &types.CompletionsRequest{
+				Prompt: "aaaabbbb",
+			},
+		},
 	}
-	cycleState3 := types.NewCycleState()
-	scores = plugin.Score(context.Background(), cycleState3, req3, pods)
-	state, err = types.ReadCycleStateKey[*SchedulingContextState](cycleState3, PrefixCachePluginType)
+	scores = plugin.Score(context.Background(), types.NewCycleState(), req3, pods)
+	state, err = plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req3.RequestId, plugins.StateKey(plugin.TypedName().String()))
 	assert.NoError(t, err)
 	t.Logf("Hashes %+v, cached servers: %+v", state.PrefixHashes, state.PrefixCacheServers)
 	// Input size is 8, hash block size is 4, so 2 hashes will be calculated.
-	// Total hashes = 3 (the first one is for the model)
-	assert.Equal(t, 3, len(state.PrefixHashes), "number of hashes is incorrect")
+	// Total hashes = 2 (the first one is for the prefix with model)
+	assert.Equal(t, 2, len(state.PrefixHashes), "number of hashes is incorrect")
 	assert.Equal(t, 1, len(state.PrefixCacheServers), "pod1 should have cached the aaaa prefix")
-	assert.Equal(t, float64(2)/float64(3), scores[pod1], "score should be 2/3 - the model and the first prefix block match")
+	assert.Equal(t, 0.5, scores[pod1], "score should be 0.5 - the model and the first prefix block match")
 	assert.Equal(t, float64(0), scores[pod2], "score for pod2")
 
-	plugin.PostCycle(context.Background(), cycleState3, &types.ProfileRunResult{TargetPods: []types.Pod{pod1}})
+	schedulingResult = &types.SchedulingResult{
+		PrimaryProfileName: "default",
+		ProfileResults: map[string]*types.ProfileRunResult{
+			"default": {TargetPods: []types.Pod{pod1}},
+		},
+	}
+	plugin.PreRequest(context.Background(), req3, schedulingResult, 0)
+	plugin.wg.Wait()
 
 	// 4th request is same as req3 except the model is different, still no match.
 	req4 := &types.LLMRequest{
+		RequestId:   uuid.NewString(),
 		TargetModel: "test-model-new",
-		Prompt:      "aaaabbbb",
+		Body: &types.LLMRequestBody{
+			Completions: &types.CompletionsRequest{
+				Prompt: "aaaabbbb",
+			},
+		},
 	}
-	cycleState4 := types.NewCycleState()
-	scores = plugin.Score(context.Background(), cycleState4, req4, pods)
-	state, err = types.ReadCycleStateKey[*SchedulingContextState](cycleState4, PrefixCachePluginType)
+	scores = plugin.Score(context.Background(), types.NewCycleState(), req4, pods)
+	state, err = plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req4.RequestId, plugins.StateKey(plugin.TypedName().String()))
 	assert.NoError(t, err)
 	t.Logf("Hashes %+v, cached servers: %+v", state.PrefixHashes, state.PrefixCacheServers)
 	// Input size is 8, hash block size is 4, so 2 hashes will be calculated.
-	// Total hashes = 3 (the first one is for the model)
-	assert.Equal(t, 3, len(state.PrefixHashes), "number of hashes is incorrect")
+	// Total hashes = 2 (the first one is for the prefix with model)
+	assert.Equal(t, 2, len(state.PrefixHashes), "number of hashes is incorrect")
 	assert.Equal(t, 0, len(state.PrefixCacheServers), "pod1 should have cached the aaaa prefix")
 	assert.Equal(t, float64(0), scores[pod1], "score for pod1")
 	assert.Equal(t, float64(0), scores[pod2], "score for pod2")
 
-	plugin.PostCycle(context.Background(), cycleState4, &types.ProfileRunResult{TargetPods: []types.Pod{pod1}})
+	schedulingResult = &types.SchedulingResult{
+		PrimaryProfileName: "default",
+		ProfileResults: map[string]*types.ProfileRunResult{
+			"default": {TargetPods: []types.Pod{pod1}},
+		},
+	}
+	plugin.PreRequest(context.Background(), req4, schedulingResult, 0)
+	plugin.wg.Wait()
 
 	// 5th request shares partial prefix with 3rd one.
 	req5 := &types.LLMRequest{
+		RequestId:   uuid.NewString(),
 		TargetModel: "test-model1",
-		Prompt:      "aaaabbbbcccc",
+		Body: &types.LLMRequestBody{
+			Completions: &types.CompletionsRequest{
+				Prompt: "aaaabbbbcccc",
+			},
+		},
 	}
-	cycleState5 := types.NewCycleState()
-	scores = plugin.Score(context.Background(), cycleState5, req5, pods)
-	state, err = types.ReadCycleStateKey[*SchedulingContextState](cycleState5, PrefixCachePluginType)
+	scores = plugin.Score(context.Background(), types.NewCycleState(), req5, pods)
+	state, err = plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req5.RequestId, plugins.StateKey(plugin.TypedName().String()))
 	assert.NoError(t, err)
 	t.Logf("Hashes %+v, cached servers: %+v", state.PrefixHashes, state.PrefixCacheServers)
 	// Input size is 12, hash block size is 4, so 3 hashes will be calculated.
-	// Total hashes = 4 (the first one is for the model)
-	assert.Equal(t, 4, len(state.PrefixHashes), "number of hashes is incorrect")
+	// Total hashes = 3 (the first one is for the prefix with model)
+	assert.Equal(t, 3, len(state.PrefixHashes), "number of hashes is incorrect")
 	assert.Equal(t, 1, len(state.PrefixCacheServers), "pod1 should have cached the aaaa prefix")
-	assert.Equal(t, 0.75, scores[pod1], "score should be 0.75 - the model and the first 2 prefix blocks match")
+	assert.Equal(t, 2./3, scores[pod1], "score should be 2./3 - the model and the first 2 prefix blocks match")
 	assert.Equal(t, float64(0), scores[pod2], "score for pod2")
 
-	plugin.PostCycle(context.Background(), cycleState5, &types.ProfileRunResult{TargetPods: []types.Pod{pod1}})
+	schedulingResult = &types.SchedulingResult{
+		PrimaryProfileName: "default",
+		ProfileResults: map[string]*types.ProfileRunResult{
+			"default": {TargetPods: []types.Pod{pod1}},
+		},
+	}
+	plugin.PreRequest(context.Background(), req5, schedulingResult, 0)
+	plugin.wg.Wait()
+}
+
+func TestPrefixPluginChatCompletions(t *testing.T) {
+	config := Config{
+		BlockSize:              4,
+		MaxPrefixBlocksToMatch: DefaultMaxPrefixBlocks,
+		LRUCapacityPerServer:   DefaultLRUCapacityPerServer,
+	}
+	plugin := New(context.Background(), config)
+
+	pod1 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}}
+	pods := []types.Pod{pod1}
+
+	// Test with chat completions request
+	req1 := &types.LLMRequest{
+		RequestId:   uuid.NewString(),
+		TargetModel: "test-model1",
+		Body: &types.LLMRequestBody{
+			ChatCompletions: &types.ChatCompletionsRequest{
+				Messages: []types.Message{
+					{Role: "user", Content: "hello world"},
+					{Role: "assistant", Content: "hi there"},
+				},
+			},
+		},
+	}
+	scores := plugin.Score(context.Background(), types.NewCycleState(), req1, pods)
+	state, err := plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req1.RequestId, plugins.StateKey(plugin.TypedName().String()))
+	assert.NoError(t, err)
+	t.Logf("Chat completions - Hashes %+v, cached servers: %+v", state.PrefixHashes, state.PrefixCacheServers)
+	// Should have some hashes for the JSON-encoded messages
+	assert.Greater(t, len(state.PrefixHashes), 1, "should have hashes for chat completions")
+	assert.Equal(t, 0, len(state.PrefixCacheServers), "there shouldn't be any cached servers initially")
+	assert.Equal(t, float64(0), scores[pod1], "score for pod1")
+}
+
+func TestPrefixPluginChatCompletionsGrowth(t *testing.T) {
+	config := Config{
+		BlockSize:              8, // Use larger block size for more predictable JSON marshaling
+		MaxPrefixBlocksToMatch: DefaultMaxPrefixBlocks,
+		LRUCapacityPerServer:   DefaultLRUCapacityPerServer,
+	}
+	plugin := New(context.Background(), config)
+
+	pod1 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}}
+	pod2 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod2"}}}
+	pods := []types.Pod{pod1, pod2}
+
+	// First request with initial conversation
+	req1 := &types.LLMRequest{
+		RequestId:   uuid.NewString(),
+		TargetModel: "test-model1",
+		Body: &types.LLMRequestBody{
+			ChatCompletions: &types.ChatCompletionsRequest{
+				Messages: []types.Message{
+					{Role: "system", Content: "You are a helpful assistant"},
+					{Role: "user", Content: "Hello, how are you?"},
+				},
+			},
+		},
+	}
+	scores := plugin.Score(context.Background(), types.NewCycleState(), req1, pods)
+	state, err := plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req1.RequestId, plugins.StateKey(plugin.TypedName().String()))
+	assert.NoError(t, err)
+	t.Logf("Initial conversation - Hashes %+v, cached servers: %+v", len(state.PrefixHashes), state.PrefixCacheServers)
+	initialHashCount := len(state.PrefixHashes)
+	assert.Greater(t, initialHashCount, 1, "should have hashes for chat completions")
+	assert.Equal(t, 0, len(state.PrefixCacheServers), "there shouldn't be any cached servers initially")
+	assert.Equal(t, float64(0), scores[pod1], "score for pod1")
+	assert.Equal(t, float64(0), scores[pod2], "score for pod2")
+
+	// Simulate pod1 was picked
+	schedulingResult := &types.SchedulingResult{
+		PrimaryProfileName: "default",
+		ProfileResults: map[string]*types.ProfileRunResult{
+			"default": {TargetPods: []types.Pod{pod1}},
+		},
+	}
+	plugin.PreRequest(context.Background(), req1, schedulingResult, 0)
+	plugin.wg.Wait()
+
+	// Second request adds assistant response and new user message (conversation grows)
+	req2 := &types.LLMRequest{
+		RequestId:   uuid.NewString(),
+		TargetModel: "test-model1",
+		Body: &types.LLMRequestBody{
+			ChatCompletions: &types.ChatCompletionsRequest{
+				Messages: []types.Message{
+					{Role: "system", Content: "You are a helpful assistant"},
+					{Role: "user", Content: "Hello, how are you?"},
+					{Role: "assistant", Content: "I'm doing well, thank you! How can I help you today?"},
+					{Role: "user", Content: "Can you explain how prefix caching works?"},
+				},
+			},
+		},
+	}
+	scores = plugin.Score(context.Background(), types.NewCycleState(), req2, pods)
+	state, err = plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req2.RequestId, plugins.StateKey(plugin.TypedName().String()))
+	assert.NoError(t, err)
+	t.Logf("Extended conversation - Hashes %+v, cached servers: %+v", len(state.PrefixHashes), state.PrefixCacheServers)
+	extendedHashCount := len(state.PrefixHashes)
+	assert.Greater(t, extendedHashCount, initialHashCount, "extended conversation should have more hashes")
+	assert.Greater(t, len(state.PrefixCacheServers), 0, "should have cached servers from prefix match")
+
+	// Calculate expected score - pod1 should have cached the initial prefix
+	cachedBlocks := state.PrefixCacheServers[ServerID(pod1.GetPod().NamespacedName)]
+	expectedScore := float64(cachedBlocks) / float64(extendedHashCount)
+	assert.Equal(t, expectedScore, scores[pod1], "pod1 should have prefix cache hit")
+	assert.Equal(t, float64(0), scores[pod2], "pod2 should have no cache hit")
+
+	// Simulate pod1 was picked again
+	plugin.PreRequest(context.Background(), req2, schedulingResult, 0)
+	plugin.wg.Wait()
+
+	// Third request continues the conversation even further
+	req3 := &types.LLMRequest{
+		RequestId:   uuid.NewString(),
+		TargetModel: "test-model1",
+		Body: &types.LLMRequestBody{
+			ChatCompletions: &types.ChatCompletionsRequest{
+				Messages: []types.Message{
+					{Role: "system", Content: "You are a helpful assistant"},
+					{Role: "user", Content: "Hello, how are you?"},
+					{Role: "assistant", Content: "I'm doing well, thank you! How can I help you today?"},
+					{Role: "user", Content: "Can you explain how prefix caching works?"},
+					{Role: "assistant", Content: "Prefix caching is a technique where..."},
+					{Role: "user", Content: "That's very helpful, thank you!"},
+				},
+			},
+		},
+	}
+	scores = plugin.Score(context.Background(), types.NewCycleState(), req3, pods)
+	state, err = plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req3.RequestId, plugins.StateKey(plugin.TypedName().String()))
+	assert.NoError(t, err)
+	t.Logf("Long conversation - Hashes %+v, cached servers: %+v", len(state.PrefixHashes), state.PrefixCacheServers)
+	longHashCount := len(state.PrefixHashes)
+	assert.Greater(t, longHashCount, extendedHashCount, "long conversation should have even more hashes")
+	assert.Greater(t, len(state.PrefixCacheServers), 0, "should have cached servers from prefix match")
+
+	// pod1 should have an even higher cache hit rate now
+	cachedBlocks = state.PrefixCacheServers[ServerID(pod1.GetPod().NamespacedName)]
+	expectedScore = float64(cachedBlocks) / float64(longHashCount)
+	assert.Equal(t, expectedScore, scores[pod1], "pod1 should have higher prefix cache hit")
+	assert.Greater(t, scores[pod1], float64(0.5), "cache hit rate should be substantial for growing conversation")
+	assert.Equal(t, float64(0), scores[pod2], "pod2 should still have no cache hit")
 }
 
 // TestPrefixPluginStress is a stress test for the prefix scoring plugin, using prompts of increasing length.
@@ -148,12 +349,12 @@ func BenchmarkPrefixPluginStress(b *testing.B) {
 	blockSize := 4
 	maxPrefixBlocks := 50000
 	config := Config{
-		HashBlockSize:          blockSize,
+		BlockSize:              blockSize,
 		MaxPrefixBlocksToMatch: maxPrefixBlocks,
 		LRUCapacityPerServer:   DefaultLRUCapacityPerServer,
 	}
 
-	plugin := New(config)
+	plugin := New(context.Background(), config)
 	types.NewCycleState()
 	var promptLen []int
 	for i := 1; i <= 1024; i++ {
@@ -174,19 +375,30 @@ func BenchmarkPrefixPluginStress(b *testing.B) {
 
 		pods := []types.Pod{pod}
 		req := &types.LLMRequest{
+			RequestId:   uuid.NewString(),
 			TargetModel: "model-stress",
-			Prompt:      prompt,
+			Body: &types.LLMRequestBody{
+				Completions: &types.CompletionsRequest{
+					Prompt: prompt,
+				},
+			},
 		}
 
 		// First cycle: simulate scheduling and insert prefix info into the cache
-		cycleState := types.NewCycleState()
-		plugin.Score(context.Background(), cycleState, req, pods)
-		plugin.PostCycle(context.Background(), cycleState, &types.ProfileRunResult{TargetPods: []types.Pod{pod}})
+		plugin.Score(context.Background(), types.NewCycleState(), req, pods)
+		schedulingResult := &types.SchedulingResult{
+			PrimaryProfileName: "default",
+			ProfileResults: map[string]*types.ProfileRunResult{
+				"default": {TargetPods: []types.Pod{pod}},
+			},
+		}
+		plugin.PreRequest(context.Background(), req, schedulingResult, 0)
+		plugin.wg.Wait()
 
 		// Second cycle: validate internal state
-		state, err := types.ReadCycleStateKey[*SchedulingContextState](cycleState, PrefixCachePluginType)
+		state, err := plugins.ReadPluginStateKey[*SchedulingContextState](plugin.pluginState, req.RequestId, plugins.StateKey(plugin.TypedName().String()))
 		assert.NoError(b, err)
-		expectedHashes := int(math.Min(float64(maxPrefixBlocks+1), float64(len(req.Prompt)/blockSize+1))) // the extra one is for the model.
+		expectedHashes := int(math.Min(float64(maxPrefixBlocks), float64(len(req.Body.Completions.Prompt)/blockSize)))
 		assert.Equal(b, expectedHashes, len(state.PrefixHashes), "number of hashes is incorrect")
 	}
 }
@@ -200,3 +412,76 @@ func randomPrompt(n int) string {
 	}
 	return sb.String()
 }
+
+// BenchmarkPrefixPluginChatCompletionsStress is a stress test for chat completions with varying message counts and lengths
+func BenchmarkPrefixPluginChatCompletionsStress(b *testing.B) {
+	blockSize := 8
+	maxPrefixBlocks := 50000
+	config := Config{
+		BlockSize:              blockSize,
+		MaxPrefixBlocksToMatch: maxPrefixBlocks,
+		LRUCapacityPerServer:   DefaultLRUCapacityPerServer,
+	}
+
+	plugin := New(context.Background(), config)
+
+	// Test scenarios: varying number of messages and message lengths
+	scenarios := []struct {
+		messageCount  int
+		messageLength int
+	}{
+		{2, 50},   // Short conversation, short messages
+		{2, 500},  // Short conversation, long messages
+		{5, 100},  // Medium conversation, medium messages
+		{10, 200}, // Long conversation, medium messages
+		{20, 100}, // Very long conversation, medium messages
+		{50, 50},  // Very long conversation, short messages
+		{100, 25}, // Extremely long conversation, very short messages
+	}
+
+	for _, scenario := range scenarios {
+		b.Run(fmt.Sprintf("messages_%d_length_%d", scenario.messageCount, scenario.messageLength), func(b *testing.B) {
+			// Generate messages for this scenario
+			messages := make([]types.Message, scenario.messageCount)
+			messages[0] = types.Message{Role: "system", Content: "You are a helpful assistant."}
+
+			for i := 1; i < scenario.messageCount; i++ {
+				role := "user"
+				if i%2 == 0 {
+					role = "assistant"
+				}
+				content := randomPrompt(scenario.messageLength)
+				messages[i] = types.Message{Role: role, Content: content}
+			}
+
+			pod := &types.PodMetrics{
+				Pod: &backend.Pod{
+					NamespacedName: k8stypes.NamespacedName{
+						Name: fmt.Sprintf("chat-pod-%d-%d", scenario.messageCount, scenario.messageLength),
+					},
+				},
+			}
+			pods := []types.Pod{pod}
+
+			req := &types.LLMRequest{
+				RequestId:   uuid.NewString(),
+				TargetModel: "chat-model-stress",
+				Body: &types.LLMRequestBody{
+					ChatCompletions: &types.ChatCompletionsRequest{
+						Messages: messages,
+					},
+				},
+			}
+
+			b.ResetTimer()
+			for i := 0; i < b.N; i++ {
+				// Benchmark the scoring operation
+				scores := plugin.Score(context.Background(), nil, req, pods)
+				_ = scores // Use the result to prevent optimization
+
+				// Clean up state for next iteration
+				plugin.pluginState.Delete(req.RequestId)
+			}
+		})
+	}
+}
diff --git a/pkg/epp/scheduling/framework/plugins/picker/picker_test.go b/pkg/epp/scheduling/framework/plugins/picker/picker_test.go
index 2c3aceb..022328e 100644
--- a/pkg/epp/scheduling/framework/plugins/picker/picker_test.go
+++ b/pkg/epp/scheduling/framework/plugins/picker/picker_test.go
@@ -18,6 +18,7 @@ package picker
 
 import (
 	"context"
+	"math"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -135,3 +136,115 @@ func TestPickMaxScorePicker(t *testing.T) {
 		})
 	}
 }
+
+func TestPickWeightedRandomPicker(t *testing.T) {
+	const (
+		testIterations = 10000
+		tolerance      = 0.05 // Verify within tolerance ±5%
+	)
+
+	pod1 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}}
+	pod2 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod2"}}}
+	pod3 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod3"}}}
+	pod4 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod4"}}}
+	pod5 := &types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod5"}}}
+
+	// A-Res algorithm uses U^(1/w) transformation which introduces statistical variance
+	// beyond simple proportional sampling. Generous tolerance is required to prevent
+	// flaky tests in CI environments, especially for multi-tier weights.
+	tests := []struct {
+		name    string
+		input   []*types.ScoredPod
+		maxPods int // maxNumOfEndpoints for this test
+	}{
+		{
+			name: "High weight dominance test",
+			input: []*types.ScoredPod{
+				{Pod: pod1, Score: 10}, // Lower weight
+				{Pod: pod2, Score: 90}, // Higher weight (should dominate)
+			},
+			maxPods: 1,
+		},
+		{
+			name: "Equal weights test - A-Res uniform distribution",
+			input: []*types.ScoredPod{
+				{Pod: pod1, Score: 100}, // Equal weights (higher values for better numerical precision)
+				{Pod: pod2, Score: 100}, // Equal weights should yield uniform distribution
+				{Pod: pod3, Score: 100}, // Equal weights in A-Res
+			},
+			maxPods: 1,
+		},
+		{
+			name: "Zero weight exclusion test - A-Res edge case",
+			input: []*types.ScoredPod{
+				{Pod: pod1, Score: 30}, // Normal weight, should be selected
+				{Pod: pod2, Score: 0},  // Zero weight, never selected in A-Res
+			},
+			maxPods: 1,
+		},
+		{
+			name: "Multi-tier weighted test - A-Res complex distribution",
+			input: []*types.ScoredPod{
+				{Pod: pod1, Score: 100}, // Highest weight
+				{Pod: pod2, Score: 90},  // High weight
+				{Pod: pod3, Score: 50},  // Medium weight
+				{Pod: pod4, Score: 30},  // Low weight
+				{Pod: pod5, Score: 20},  // Lowest weight
+			},
+			maxPods: 1,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			picker := NewWeightedRandomPicker(test.maxPods)
+
+			// Summarize the total score of all pods
+			totalScore := 0.0
+			for _, pod := range test.input {
+				totalScore += pod.Score
+			}
+
+			// Calculate expected probabilities based on scores
+			expectedProbabilities := make(map[string]float64)
+			for _, pod := range test.input {
+				podName := pod.GetPod().NamespacedName.Name
+				if totalScore > 0 {
+					expectedProbabilities[podName] = pod.Score / totalScore
+				} else {
+					expectedProbabilities[podName] = 0.0
+				}
+			}
+
+			// Initialize selection counters for each pod
+			selectionCounts := make(map[string]int)
+			for _, pod := range test.input {
+				podName := pod.GetPod().NamespacedName.Name
+				selectionCounts[podName] = 0
+			}
+
+			// Run multiple iterations to gather statistical data
+			for range testIterations {
+				result := picker.Pick(context.Background(), types.NewCycleState(), test.input)
+
+				// Count selections for probability analysis
+				selectedPodName := result.TargetPods[0].GetPod().NamespacedName.Name
+				selectionCounts[selectedPodName]++
+			}
+
+			// Verify probability distribution
+			for podName, expectedProb := range expectedProbabilities {
+				actualCount := selectionCounts[podName]
+				actualProb := float64(actualCount) / float64(testIterations)
+
+				if math.Abs(actualProb-expectedProb) > tolerance {
+					t.Errorf("Pod %s: expected probability %.3f ±%.1f%%, got %.3f (count: %d/%d)",
+						podName, expectedProb, tolerance*100, actualProb, actualCount, testIterations)
+				} else {
+					t.Logf("Pod %s: expected %.3f, got %.3f (count: %d/%d) ✓",
+						podName, expectedProb, actualProb, actualCount, testIterations)
+				}
+			}
+		})
+	}
+}
diff --git a/pkg/epp/scheduling/framework/scheduler_profile_test.go b/pkg/epp/scheduling/framework/scheduler_profile_test.go
index 020223c..f79b48d 100644
--- a/pkg/epp/scheduling/framework/scheduler_profile_test.go
+++ b/pkg/epp/scheduling/framework/scheduler_profile_test.go
@@ -64,8 +64,7 @@ func TestSchedulePlugins(t *testing.T) {
 			profile: NewSchedulerProfile().
 				WithFilters(tp1, tp2).
 				WithScorers(NewWeightedScorer(tp1, 1), NewWeightedScorer(tp2, 1)).
-				WithPicker(pickerPlugin).
-				WithPostCyclePlugins(tp1, tp2),
+				WithPicker(pickerPlugin),
 			input: []types.Pod{
 				&types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}},
 				&types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod2"}}},
@@ -81,8 +80,7 @@ func TestSchedulePlugins(t *testing.T) {
 			profile: NewSchedulerProfile().
 				WithFilters(tp1, tp2).
 				WithScorers(NewWeightedScorer(tp1, 60), NewWeightedScorer(tp2, 40)).
-				WithPicker(pickerPlugin).
-				WithPostCyclePlugins(tp1, tp2),
+				WithPicker(pickerPlugin),
 			input: []types.Pod{
 				&types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}},
 				&types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod2"}}},
@@ -98,8 +96,7 @@ func TestSchedulePlugins(t *testing.T) {
 			profile: NewSchedulerProfile().
 				WithFilters(tp1, tp_filterAll).
 				WithScorers(NewWeightedScorer(tp1, 1), NewWeightedScorer(tp2, 1)).
-				WithPicker(pickerPlugin).
-				WithPostCyclePlugins(tp1, tp2),
+				WithPicker(pickerPlugin),
 			input: []types.Pod{
 				&types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}},
 				&types.PodMetrics{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod2"}}},
@@ -120,9 +117,6 @@ func TestSchedulePlugins(t *testing.T) {
 				plugin.Scorer.(*testPlugin).reset()
 			}
 			test.profile.picker.(*testPlugin).reset()
-			for _, plugin := range test.profile.postCyclePlugins {
-				plugin.(*testPlugin).reset()
-			}
 
 			// Initialize the scheduling context
 			request := &types.LLMRequest{
@@ -179,12 +173,6 @@ func TestSchedulePlugins(t *testing.T) {
 			if tp.WinnerPodScore != test.targetPodScore {
 				t.Errorf("winner pod score %v, expected %v", tp.WinnerPodScore, test.targetPodScore)
 			}
-			for _, plugin := range test.profile.postCyclePlugins {
-				tp, _ := plugin.(*testPlugin)
-				if tp.PostCycleCallCount != 1 {
-					t.Errorf("Plugin '%s' PostCycle() called %d times, expected 1", plugin.TypedName(), tp.PostCycleCallCount)
-				}
-			}
 		})
 	}
 }
@@ -193,7 +181,6 @@ func TestSchedulePlugins(t *testing.T) {
 var _ Filter = &testPlugin{}
 var _ Scorer = &testPlugin{}
 var _ Picker = &testPlugin{}
-var _ PostCycle = &testPlugin{}
 
 // testPlugin is an implementation useful in unit tests.
 type testPlugin struct {
@@ -204,7 +191,6 @@ type testPlugin struct {
 	ScoreRes              float64
 	FilterCallCount       int
 	FilterRes             []k8stypes.NamespacedName
-	PostCycleCallCount    int
 	PickCallCount         int
 	NumOfPickerCandidates int
 	PickRes               k8stypes.NamespacedName
@@ -246,15 +232,10 @@ func (tp *testPlugin) Pick(_ context.Context, _ *types.CycleState, scoredPods []
 	return &types.ProfileRunResult{TargetPods: winnerPods}
 }
 
-func (tp *testPlugin) PostCycle(_ context.Context, _ *types.CycleState, res *types.ProfileRunResult) {
-	tp.PostCycleCallCount++
-}
-
 func (tp *testPlugin) reset() {
 	tp.FilterCallCount = 0
 	tp.ScoreCallCount = 0
 	tp.NumOfScoredPods = 0
-	tp.PostCycleCallCount = 0
 	tp.PickCallCount = 0
 	tp.NumOfPickerCandidates = 0
 }
diff --git a/pkg/epp/scheduling/scheduler_test.go b/pkg/epp/scheduling/scheduler_test.go
index aea9c57..c197096 100644
--- a/pkg/epp/scheduling/scheduler_test.go
+++ b/pkg/epp/scheduling/scheduler_test.go
@@ -38,7 +38,7 @@ import (
 func TestSchedule(t *testing.T) {
 	kvCacheUtilizationScorer := scorer.NewKVCacheUtilizationScorer()
 	queueingScorer := scorer.NewQueueScorer()
-	prefixCacheScorer := prefix.New(prefix.DefaultConfig)
+	prefixCacheScorer := prefix.New(context.Background(), prefix.DefaultConfig)
 	loraAffinityScorer := scorer.NewLoraAffinityScorer()
 
 	defaultProfile := framework.NewSchedulerProfile().
diff --git a/pkg/epp/server/server_test.go b/pkg/epp/server/server_test.go
index dfcc4bb..aff6d46 100644
--- a/pkg/epp/server/server_test.go
+++ b/pkg/epp/server/server_test.go
@@ -42,13 +42,10 @@ const (
 )
 
 func TestServer(t *testing.T) {
-	theHeaderValue := "body"
-	requestHeader := "x-test"
-
 	expectedRequestHeaders := map[string]string{metadata.DestinationEndpointKey: fmt.Sprintf("%s:%d", podAddress, poolPort),
-		"Content-Length": "42", ":method": "POST", requestHeader: theHeaderValue}
-	expectedResponseHeaders := map[string]string{"x-went-into-resp-headers": "true", ":method": "POST", requestHeader: theHeaderValue}
-	expectedSchedulerHeaders := map[string]string{":method": "POST", requestHeader: theHeaderValue}
+		"Content-Length": "42", ":method": "POST", "x-test": "body", "x-request-id": "test-request-id"}
+	expectedResponseHeaders := map[string]string{"x-went-into-resp-headers": "true", ":method": "POST", "x-test": "body"}
+	expectedSchedulerHeaders := map[string]string{":method": "POST", "x-test": "body", "x-request-id": "test-request-id"}
 
 	t.Run("server", func(t *testing.T) {
 		model := testutil.MakeInferenceObjective("v1").
@@ -66,9 +63,10 @@ func TestServer(t *testing.T) {
 
 		// Send request headers - no response expected
 		headers := utils.BuildEnvoyGRPCHeaders(map[string]string{
-			requestHeader:              theHeaderValue,
+			"x-test":                   "body",
 			":method":                  "POST",
 			metadata.FlowFairnessIDKey: "a-very-interesting-fairness-id",
+			"x-request-id":             "test-request-id",
 		}, true)
 		request := &pb.ProcessingRequest{
 			Request: &pb.ProcessingRequest_RequestHeaders{
@@ -130,9 +128,6 @@ func TestServer(t *testing.T) {
 		}
 
 		// Check headers passed to the scheduler
-		if len(director.requestHeaders) != 2 {
-			t.Errorf("Incorrect number of request headers %d instead of 2", len(director.requestHeaders))
-		}
 		for expectedKey, expectedValue := range expectedSchedulerHeaders {
 			got, ok := director.requestHeaders[expectedKey]
 			if !ok {
@@ -143,7 +138,7 @@ func TestServer(t *testing.T) {
 		}
 
 		// Send response headers
-		headers = utils.BuildEnvoyGRPCHeaders(map[string]string{requestHeader: theHeaderValue, ":method": "POST"}, false)
+		headers = utils.BuildEnvoyGRPCHeaders(map[string]string{"x-test": "body", ":method": "POST"}, false)
 		request = &pb.ProcessingRequest{
 			Request: &pb.ProcessingRequest_ResponseHeaders{
 				ResponseHeaders: headers,
diff --git a/pkg/epp/util/request/body_test.go b/pkg/epp/util/request/body_test.go
index ce5a939..51389e5 100644
--- a/pkg/epp/util/request/body_test.go
+++ b/pkg/epp/util/request/body_test.go
@@ -18,16 +18,30 @@ package request
 
 import (
 	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
 )
 
-func TestExtractPromptFromRequestBody(t *testing.T) {
+func TestExtractRequestData(t *testing.T) {
 	tests := []struct {
 		name    string
 		body    map[string]any
-		want    string
+		want    *types.LLMRequestBody
 		wantErr bool
-		errType error
 	}{
+		{
+			name: "completions request body",
+			body: map[string]any{
+				"model":  "test",
+				"prompt": "test prompt",
+			},
+			want: &types.LLMRequestBody{
+				Completions: &types.CompletionsRequest{
+					Prompt: "test prompt",
+				},
+			},
+		},
 		{
 			name: "chat completions request body",
 			body: map[string]any{
@@ -39,169 +53,289 @@ func TestExtractPromptFromRequestBody(t *testing.T) {
 					map[string]any{
 						"role": "user", "content": "hello",
 					},
-					map[string]any{
-						"role": "assistant", "content": "hi, what can I do for you?",
+				},
+			},
+			want: &types.LLMRequestBody{
+				ChatCompletions: &types.ChatCompletionsRequest{
+					Messages: []types.Message{
+						{Role: "system", Content: "this is a system message"},
+						{Role: "user", Content: "hello"},
 					},
 				},
 			},
-			want: "
system\nthis is a system message
\n" +
-				"
user\nhello
\n" +
-				"
assistant\nhi, what can I do for you?
\n",
 		},
 		{
-			name: "completions request body",
+			name: "chat completions with all optional fields",
 			body: map[string]any{
-				"model":  "test",
-				"prompt": "test prompt",
+				"model": "test",
+				"messages": []any{
+					map[string]any{"role": "user", "content": "hello"},
+				},
+				"tools":                        []any{map[string]any{"type": "function"}},
+				"documents":                    []any{map[string]any{"content": "doc"}},
+				"chat_template":                "custom template",
+				"return_assistant_tokens_mask": true,
+				"continue_final_message":       true,
+				"add_generation_prompt":        true,
+				"chat_template_kwargs":         map[string]any{"key": "value"},
+			},
+			want: &types.LLMRequestBody{
+				ChatCompletions: &types.ChatCompletionsRequest{
+					Messages:                  []types.Message{{Role: "user", Content: "hello"}},
+					Tools:                     []any{map[string]any{"type": "function"}},
+					Documents:                 []any{map[string]any{"content": "doc"}},
+					ChatTemplate:              "custom template",
+					ReturnAssistantTokensMask: true,
+					ContinueFinalMessage:      true,
+					AddGenerationPrompt:       true,
+					ChatTemplateKWArgs:        map[string]any{"key": "value"},
+				},
 			},
-			want: "test prompt",
+		},
+		{
+			name:    "nil body",
+			body:    nil,
+			wantErr: true,
 		},
 		{
 			name: "invalid prompt format",
+			body: map[string]any{
+				"model":  "test",
+				"prompt": 123,
+			},
+			wantErr: true,
+		},
+		{
+			name: "invalid messages format",
+			body: map[string]any{
+				"model":    "test",
+				"messages": "invalid",
+			},
+			wantErr: true,
+		},
+		{
+			name: "neither prompt nor messages",
 			body: map[string]any{
 				"model": "test",
-				"prompt": []any{
-					map[string]any{
-						"role": "system", "content": "this is a system message",
-					},
-					map[string]any{
-						"role": "user", "content": "hello",
-					},
-					map[string]any{
-						"role": "assistant", "content": "hi, what can I",
-					},
+			},
+			wantErr: true,
+		},
+		{
+			name: "empty messages array",
+			body: map[string]any{
+				"model":    "test",
+				"messages": []any{},
+			},
+			wantErr: true,
+		},
+		{
+			name: "message with non-string role",
+			body: map[string]any{
+				"model": "test",
+				"messages": []any{
+					map[string]any{"role": 123, "content": "hello"},
 				},
 			},
 			wantErr: true,
 		},
 		{
-			name: "invalid messaged format",
+			name: "message with non-string content",
 			body: map[string]any{
 				"model": "test",
-				"messages": map[string]any{
-					"role": "system", "content": "this is a system message",
+				"messages": []any{
+					map[string]any{"role": "user", "content": 123},
 				},
 			},
 			wantErr: true,
 		},
 		{
-			name: "prompt does not exist",
+			name: "invalid tools format",
 			body: map[string]any{
 				"model": "test",
+				"messages": []any{
+					map[string]any{"role": "user", "content": "hello"},
+				},
+				"tools": "invalid",
 			},
 			wantErr: true,
 		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := ExtractPromptFromRequestBody(tt.body)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("ExtractPromptFromRequestBody() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("ExtractPromptFromRequestBody() got = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestExtractPromptField(t *testing.T) {
-	tests := []struct {
-		name    string
-		body    map[string]any
-		want    string
-		wantErr bool
-	}{
 		{
-			name: "valid prompt",
+			name: "invalid documents format",
 			body: map[string]any{
-				"prompt": "test prompt",
+				"model": "test",
+				"messages": []any{
+					map[string]any{"role": "user", "content": "hello"},
+				},
+				"documents": "invalid",
+			},
+			wantErr: true,
+		},
+		{
+			name: "invalid chat_template format",
+			body: map[string]any{
+				"model": "test",
+				"messages": []any{
+					map[string]any{"role": "user", "content": "hello"},
+				},
+				"chat_template": 123,
 			},
-			want: "test prompt",
+			wantErr: true,
 		},
 		{
-			name:    "prompt not found",
-			body:    map[string]any{},
+			name: "invalid return_assistant_tokens_mask format",
+			body: map[string]any{
+				"model": "test",
+				"messages": []any{
+					map[string]any{"role": "user", "content": "hello"},
+				},
+				"return_assistant_tokens_mask": "invalid",
+			},
 			wantErr: true,
 		},
 		{
-			name: "non-string prompt",
+			name: "invalid continue_final_message format",
 			body: map[string]any{
-				"prompt": 123,
+				"model": "test",
+				"messages": []any{
+					map[string]any{"role": "user", "content": "hello"},
+				},
+				"continue_final_message": "invalid",
 			},
 			wantErr: true,
 		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := extractPromptField(tt.body)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("extractPromptField() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("extractPromptField() got = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestExtractPromptFromMessagesField(t *testing.T) {
-	tests := []struct {
-		name    string
-		body    map[string]any
-		want    string
-		wantErr bool
-	}{
 		{
-			name: "valid messages",
+			name: "invalid add_generation_prompt format",
 			body: map[string]any{
+				"model": "test",
 				"messages": []any{
-					map[string]any{"role": "user", "content": "test1"},
-					map[string]any{"role": "assistant", "content": "test2"},
+					map[string]any{"role": "user", "content": "hello"},
 				},
+				"add_generation_prompt": "invalid",
 			},
-			want: "
user\ntest1
\n
assistant\ntest2
\n",
+			wantErr: true,
 		},
 		{
-			name: "invalid messages format",
+			name: "invalid chat_template_kwargs format",
 			body: map[string]any{
-				"messages": "invalid",
+				"model": "test",
+				"messages": []any{
+					map[string]any{"role": "user", "content": "hello"},
+				},
+				"chat_template_kwargs": "invalid",
 			},
 			wantErr: true,
 		},
+		{
+			name: "completions request with cache_salt",
+			body: map[string]any{
+				"model":      "test",
+				"prompt":     "test prompt",
+				"cache_salt": "Z3V2bmV3aGxza3ZubGFoZ3Zud3V3ZWZ2bmd0b3V2bnZmc2xpZ3RoZ2x2aQ==",
+			},
+			want: &types.LLMRequestBody{
+				Completions: &types.CompletionsRequest{
+					Prompt:    "test prompt",
+					CacheSalt: "Z3V2bmV3aGxza3ZubGFoZ3Zud3V3ZWZ2bmd0b3V2bnZmc2xpZ3RoZ2x2aQ==",
+				},
+			},
+		},
+		{
+			name: "chat completions request with cache_salt",
+			body: map[string]any{
+				"model": "test",
+				"messages": []any{
+					map[string]any{
+						"role": "system", "content": "this is a system message",
+					},
+					map[string]any{
+						"role": "user", "content": "hello",
+					},
+				},
+				"cache_salt": "Z3V2bmV3aGxza3ZubGFoZ3Zud3V3ZWZ2bmd0b3V2bnZmc2xpZ3RoZ2x2aQ==",
+			},
+			want: &types.LLMRequestBody{
+				ChatCompletions: &types.ChatCompletionsRequest{
+					Messages: []types.Message{
+						{Role: "system", Content: "this is a system message"},
+						{Role: "user", Content: "hello"},
+					},
+					CacheSalt: "Z3V2bmV3aGxza3ZubGFoZ3Zud3V3ZWZ2bmd0b3V2bnZmc2xpZ3RoZ2x2aQ==",
+				},
+			},
+		},
 	}
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := extractPromptFromMessagesField(tt.body)
+			got, err := ExtractRequestBody(tt.body)
 			if (err != nil) != tt.wantErr {
-				t.Errorf("extractPromptFromMessagesField() error = %v, wantErr %v", err, tt.wantErr)
+				t.Errorf("ExtractRequestBody() error = %v, wantErr %v", err, tt.wantErr)
 				return
 			}
-			if got != tt.want {
-				t.Errorf("extractPromptFromMessagesField() got = %v, want %v", got, tt.want)
+			if tt.wantErr {
+				return
+			}
+
+			if diff := cmp.Diff(tt.want, got); diff != "" {
+				t.Errorf("ExtractRequestBody() mismatch (-want +got):\n%s", diff)
 			}
 		})
 	}
 }
 
-func TestConstructChatMessage(t *testing.T) {
-	tests := []struct {
-		role    string
-		content string
-		want    string
-	}{
-		{"user", "hello", "
user\nhello
\n"},
-		{"assistant", "hi", "
assistant\nhi
\n"},
+// Benchmark tests for performance comparison
+func BenchmarkExtractRequestData_Completions(b *testing.B) {
+	body := map[string]any{
+		"model":  "test",
+		"prompt": "test prompt",
 	}
 
-	for _, tt := range tests {
-		if got := constructChatMessage(tt.role, tt.content); got != tt.want {
-			t.Errorf("constructChatMessage() = %v, want %v", got, tt.want)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, err := ExtractRequestBody(body)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkExtractRequestData_ChatCompletions(b *testing.B) {
+	body := map[string]any{
+		"model": "test",
+		"messages": []any{
+			map[string]any{"role": "user", "content": "hello"},
+		},
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, err := ExtractRequestBody(body)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkExtractRequestData_ChatCompletionsWithOptionals(b *testing.B) {
+	body := map[string]any{
+		"model": "test",
+		"messages": []any{
+			map[string]any{"role": "user", "content": "hello"},
+		},
+		"tools":                        []any{map[string]any{"type": "function"}},
+		"documents":                    []any{map[string]any{"content": "doc"}},
+		"chat_template":                "custom template",
+		"return_assistant_tokens_mask": true,
+		"continue_final_message":       true,
+		"add_generation_prompt":        true,
+		"chat_template_kwargs":         map[string]any{"key": "value"},
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, err := ExtractRequestBody(body)
+		if err != nil {
+			b.Fatal(err)
 		}
 	}
 }
diff --git a/pkg/epp/util/testing/wrappers.go b/pkg/epp/util/testing/wrappers.go
index 9eeb3ad..9e7f4a1 100644
--- a/pkg/epp/util/testing/wrappers.go
+++ b/pkg/epp/util/testing/wrappers.go
@@ -205,8 +205,8 @@ func (m *InferencePoolWrapper) TargetPorts(p int32) *InferencePoolWrapper {
 	return m
 }
 
-func (m *InferencePoolWrapper) ExtensionRef(name string) *InferencePoolWrapper {
-	m.Spec.ExtensionRef = v1.Extension{Name: v1.ObjectName(name)}
+func (m *InferencePoolWrapper) EndpointPickerRef(name string) *InferencePoolWrapper {
+	m.Spec.EndpointPickerRef = v1.EndpointPickerRef{Name: v1.ObjectName(name)}
 	return m
 }
 
diff --git a/test/cel/inferencepool_test.go b/test/cel/inferencepool_test.go
new file mode 100644
index 0000000..deccb6e
--- /dev/null
+++ b/test/cel/inferencepool_test.go
@@ -0,0 +1,128 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+	"context"
+	"fmt"
+	"testing"
+	"time"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+)
+
+func TestValidateInferencePool(t *testing.T) {
+	ctx := context.Background()
+
+	// baseInferencePool is a valid, InferencePool resource.
+	baseInferencePool := v1.InferencePool{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      "base-pool",
+			Namespace: metav1.NamespaceDefault,
+		},
+		Spec: v1.InferencePoolSpec{
+			TargetPorts: []v1.Port{
+				{Number: 8000},
+			},
+			Selector: v1.LabelSelector{
+				MatchLabels: map[v1.LabelKey]v1.LabelValue{
+					"app": "model-server",
+				},
+			},
+			EndpointPickerRef: v1.EndpointPickerRef{
+				Name: "epp",
+				Kind: "Service",
+				Port: ptrTo(v1.Port{Number: 9002}),
+			},
+		},
+	}
+
+	testCases := []struct {
+		desc       string
+		mutate     func(ip *v1.InferencePool)
+		wantErrors []string
+	}{
+		{
+			desc: "passes validation with a valid configuration",
+			mutate: func(ip *v1.InferencePool) {
+			},
+			wantErrors: nil,
+		},
+		{
+			desc: "fails validation when kind is unset (defaults to Service) and port is missing",
+			mutate: func(ip *v1.InferencePool) {
+				// By setting Kind to an empty string, we rely on the API server's default value of "Service".
+				ip.Spec.EndpointPickerRef.Kind = ""
+				ip.Spec.EndpointPickerRef.Port = nil
+			},
+			wantErrors: []string{"port is required when kind is 'Service' or unspecified (defaults to 'Service')"},
+		},
+		{
+			desc: "fails validation when kind is explicitly 'Service' and port is missing",
+			mutate: func(ip *v1.InferencePool) {
+				ip.Spec.EndpointPickerRef.Kind = "Service"
+				ip.Spec.EndpointPickerRef.Port = nil
+			},
+			wantErrors: []string{"port is required when kind is 'Service' or unspecified (defaults to 'Service')"},
+		},
+		{
+			desc: "passes validation with multiple unique port numbers",
+			mutate: func(ip *v1.InferencePool) {
+				ip.Spec.TargetPorts = []v1.Port{{Number: 8000}, {Number: 80}, {Number: 8081}, {Number: 443}}
+			},
+			wantErrors: nil,
+		},
+		{
+			desc: "fails validation with port numbers containing duplicates",
+			mutate: func(ip *v1.InferencePool) {
+				ip.Spec.TargetPorts = []v1.Port{{Number: 8000}, {Number: 80}, {Number: 8000}, {Number: 443}}
+			},
+			wantErrors: []string{"port number must be unique"},
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.desc, func(t *testing.T) {
+			ip := baseInferencePool.DeepCopy()
+			// Use a unique name for each test case to avoid conflicts.
+			ip.Name = fmt.Sprintf("test-pool-%v", time.Now().UnixNano())
+
+			if tc.mutate != nil {
+				tc.mutate(ip)
+			}
+			err := k8sClient.Create(ctx, ip)
+
+			// This is a boolean XOR. It's true if one is true, but not both.
+			// It ensures that an error is returned if and only if we expect one.
+			if (len(tc.wantErrors) != 0) != (err != nil) {
+				t.Fatalf("Unexpected response while creating InferencePool; got err=\n%v\n; want error=%v", err, tc.wantErrors != nil)
+			}
+
+			// If we got an error, check that it contains the expected substrings.
+			var missingErrorStrings []string
+			for _, wantError := range tc.wantErrors {
+				if !celErrorStringMatches(err.Error(), wantError) {
+					missingErrorStrings = append(missingErrorStrings, wantError)
+				}
+			}
+			if len(missingErrorStrings) != 0 {
+				t.Errorf("Unexpected response while creating InferencePool; got err=\n%v\n; missing strings within error=%q", err, missingErrorStrings)
+			}
+		})
+	}
+}
diff --git a/test/cel/main_test.go b/test/cel/main_test.go
new file mode 100644
index 0000000..2758a56
--- /dev/null
+++ b/test/cel/main_test.go
@@ -0,0 +1,130 @@
+/*
+Copyright 2023 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/rest"
+	"k8s.io/client-go/tools/clientcmd"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/envtest"
+
+	inferencev1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
+	inferencev1alpha2 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
+)
+
+var k8sClient client.Client
+
+func TestMain(m *testing.M) {
+	scheme := runtime.NewScheme()
+	var restConfig *rest.Config
+	var testEnv *envtest.Environment
+	var err error
+
+	_ = inferencev1.Install(scheme)
+	_ = inferencev1alpha2.Install(scheme)
+
+	// Add core APIs in case we refer secrets, services and configmaps
+	_ = corev1.AddToScheme(scheme)
+
+	// If one wants to use a local cluster, a KUBECONFIG envvar should be passed,
+	// otherwise testenv will be used
+	kubeconfig := os.Getenv("KUBECONFIG")
+	if kubeconfig != "" {
+		restConfig, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
+		if err != nil {
+			panic(fmt.Sprintf("Failed to get restConfig from BuildConfigFromFlags: %v", err))
+		}
+	} else {
+		// The version used here MUST reflect the available versions at
+		// controller-runtime repo: https://raw.githubusercontent.com/kubernetes-sigs/controller-tools/HEAD/envtest-releases.yaml
+		// If the envvar is not passed, the latest GA will be used
+		k8sVersion := os.Getenv("K8S_VERSION")
+		testEnv = &envtest.Environment{
+			Scheme:                      scheme,
+			ErrorIfCRDPathMissing:       true,
+			DownloadBinaryAssets:        true,
+			DownloadBinaryAssetsVersion: k8sVersion,
+			CRDInstallOptions: envtest.CRDInstallOptions{
+				Paths: []string{
+					filepath.Join("..", "..", "config", "crd", "bases"),
+				},
+				CleanUpAfterUse: true,
+			},
+		}
+
+		restConfig, err = testEnv.Start()
+		if err != nil {
+			panic(fmt.Sprintf("Error initializing test environment: %v", err))
+		}
+	}
+
+	k8sClient, err = client.New(restConfig, client.Options{
+		Scheme: scheme,
+	})
+	if err != nil {
+		panic(fmt.Sprintf("Error initializing Kubernetes client: %v", err))
+	}
+
+	rc := m.Run()
+	if testEnv != nil {
+		if err := testEnv.Stop(); err != nil {
+			panic(fmt.Sprintf("error stopping test environment: %v", err))
+		}
+	}
+
+	os.Exit(rc)
+}
+
+func ptrTo[T any](a T) *T {
+	return &a
+}
+
+func celErrorStringMatches(got, want string) bool {
+	gotL := strings.ToLower(got)
+	wantL := strings.ToLower(want)
+
+	// Starting in k8s v1.32, some CEL error messages changed to use "more" instead of "longer"
+	alternativeWantL := strings.ReplaceAll(wantL, "longer", "more")
+
+	// Starting in k8s v1.28, CEL error messages stopped adding spec and status prefixes to path names
+	wantLAdjusted := strings.ReplaceAll(wantL, "spec.", "")
+	wantLAdjusted = strings.ReplaceAll(wantLAdjusted, "status.", "")
+	alternativeWantL = strings.ReplaceAll(alternativeWantL, "spec.", "")
+	alternativeWantL = strings.ReplaceAll(alternativeWantL, "status.", "")
+
+	// Enum validation messages changed in k8s v1.28:
+	// Before: must be one of ['Exact', 'PathPrefix', 'RegularExpression']
+	// After: supported values: "Exact", "PathPrefix", "RegularExpression"
+	if strings.Contains(wantLAdjusted, "must be one of") {
+		r := strings.NewReplacer(
+			"must be one of", "supported values:",
+			"[", "",
+			"]", "",
+			"'", "\"",
+		)
+		wantLAdjusted = r.Replace(wantLAdjusted)
+	}
+	return strings.Contains(gotL, wantL) || strings.Contains(gotL, wantLAdjusted) || strings.Contains(gotL, alternativeWantL)
+}
diff --git a/test/e2e/epp/e2e_suite_test.go b/test/e2e/epp/e2e_suite_test.go
index e6e5b83..b41f108 100644
--- a/test/e2e/epp/e2e_suite_test.go
+++ b/test/e2e/epp/e2e_suite_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package epp
 
 import (
-	"context"
 	"errors"
 	"fmt"
 	"os"
@@ -29,34 +28,20 @@ import (
 	"github.com/onsi/gomega"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
-	rbacv1 "k8s.io/api/rbac/v1"
 	apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/runtime/serializer"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/client-go/kubernetes"
 	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/client/config"
 
 	infextv1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
 	infextv1a2 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/env"
 	testutils "sigs.k8s.io/gateway-api-inference-extension/test/utils"
 )
 
 const (
-	// defaultExistsTimeout is the default timeout for a resource to exist in the api server.
-	defaultExistsTimeout = 30 * time.Second
-	// defaultReadyTimeout is the default timeout for a resource to report a ready state.
-	defaultReadyTimeout = 3 * time.Minute
-	// defaultModelReadyTimeout is the default timeout for the model server deployment to report a ready state.
-	defaultModelReadyTimeout = 10 * time.Minute
 	// defaultCurlTimeout is the default timeout for the curl command to get a response.
 	defaultCurlTimeout = 30 * time.Second
-	// defaultInterval is the default interval to check if a resource exists or ready conditions.
-	defaultInterval = time.Millisecond * 250
 	// defaultCurlInterval is the default interval to run the test curl command.
 	defaultCurlInterval = time.Second * 5
 	// defaultNsName is the default name of the Namespace used for tests. Can override using the E2E_NS environment variable.
@@ -100,13 +85,8 @@ const (
 const e2eLeaderElectionEnabledEnvVar = "E2E_LEADER_ELECTION_ENABLED"
 
 var (
-	ctx = context.Background()
-	cli client.Client
+	testConfig *testutils.TestConfig
 	// Required for exec'ing in curl pod
-	kubeCli               *kubernetes.Clientset
-	scheme                = runtime.NewScheme()
-	cfg                   = config.GetConfigOrDie()
-	nsName                string
 	e2eImage              string
 	leaderElectionEnabled bool
 )
@@ -119,10 +99,12 @@ func TestAPIs(t *testing.T) {
 }
 
 var _ = ginkgo.BeforeSuite(func() {
-	nsName = os.Getenv("E2E_NS")
+	nsName := os.Getenv("E2E_NS")
 	if nsName == "" {
 		nsName = defaultNsName
 	}
+	testConfig = testutils.NewTestConfig(nsName)
+
 	e2eImage = os.Getenv("E2E_IMAGE")
 	gomega.Expect(e2eImage).NotTo(gomega.BeEmpty(), "E2E_IMAGE environment variable is not set")
 
@@ -143,11 +125,11 @@ func setupInfra() {
 	// run this before createNs to fail fast in case it doesn't.
 	modelServerManifestPath := readModelServerManifestPath()
 
-	createNamespace(cli, nsName)
+	createNamespace(testConfig)
 
 	modelServerManifestArray := getYamlsFromModelServerManifest(modelServerManifestPath)
 	if strings.Contains(modelServerManifestArray[0], "hf-token") {
-		createHfSecret(cli, modelServerSecretManifest)
+		createHfSecret(testConfig, modelServerSecretManifest)
 	}
 	crds := map[string]string{
 		"inferencepools.inference.networking.x-k8s.io":      xInferPoolManifest,
@@ -155,19 +137,19 @@ func setupInfra() {
 		"inferencepools.inference.networking.k8s.io":        inferPoolManifest,
 	}
 
-	createCRDs(cli, crds)
+	createCRDs(testConfig, crds)
 
 	inferExtManifestPath := inferExtManifestDefault
 	if leaderElectionEnabled {
 		inferExtManifestPath = inferExtManifestLeaderElection
 	}
-	createInferExt(cli, inferExtManifestPath)
-	createClient(cli, clientManifest)
-	createEnvoy(cli, envoyManifest)
-	createMetricsRbac(cli, metricsRbacManifest)
+	createInferExt(testConfig, inferExtManifestPath)
+	createClient(testConfig, clientManifest)
+	createEnvoy(testConfig, envoyManifest)
+	createMetricsRbac(testConfig, metricsRbacManifest)
 	// Run this step last, as it requires additional time for the model server to become ready.
 	ginkgo.By("Creating model server resources from manifest: " + modelServerManifestPath)
-	createModelServer(cli, modelServerManifestArray)
+	createModelServer(testConfig, modelServerManifestArray)
 }
 
 var _ = ginkgo.AfterSuite(func() {
@@ -192,77 +174,57 @@ var _ = ginkgo.AfterSuite(func() {
 // setupSuite initializes the test suite by setting up the Kubernetes client,
 // loading required API schemes, and validating configuration.
 func setupSuite() {
-	gomega.ExpectWithOffset(1, cfg).NotTo(gomega.BeNil())
-
-	err := clientgoscheme.AddToScheme(scheme)
+	err := clientgoscheme.AddToScheme(testConfig.Scheme)
 	gomega.ExpectWithOffset(1, err).NotTo(gomega.HaveOccurred())
 
-	err = apiextv1.AddToScheme(scheme)
+	err = apiextv1.AddToScheme(testConfig.Scheme)
 	gomega.ExpectWithOffset(1, err).NotTo(gomega.HaveOccurred())
 
-	err = infextv1a2.Install(scheme)
+	err = infextv1a2.Install(testConfig.Scheme)
 	gomega.ExpectWithOffset(1, err).NotTo(gomega.HaveOccurred())
 
-	err = infextv1.Install(scheme)
+	err = infextv1.Install(testConfig.Scheme)
 	gomega.ExpectWithOffset(1, err).NotTo(gomega.HaveOccurred())
 
-	cli, err = client.New(cfg, client.Options{Scheme: scheme})
-	gomega.Expect(err).NotTo(gomega.HaveOccurred())
-	gomega.Expect(cli).NotTo(gomega.BeNil())
-
-	kubeCli, err = kubernetes.NewForConfig(cfg)
-	gomega.Expect(err).NotTo(gomega.HaveOccurred())
-	gomega.Expect(kubeCli).NotTo(gomega.BeNil())
+	testConfig.CreateCli()
 }
 
 func cleanupResources() {
-	if cli == nil {
+	if testConfig.K8sClient == nil {
 		return // could happen if BeforeSuite had an error
 	}
 
-	gomega.Expect(testutils.DeleteClusterResources(ctx, cli)).To(gomega.Succeed())
-	gomega.Expect(testutils.DeleteNamespacedResources(ctx, cli, nsName)).To(gomega.Succeed())
+	gomega.Expect(testutils.DeleteClusterResources(testConfig)).To(gomega.Succeed())
+	gomega.Expect(testutils.DeleteNamespacedResources(testConfig)).To(gomega.Succeed())
 }
 
 func cleanupInferModelResources() {
-	gomega.Expect(testutils.DeleteInferenceObjectiveResources(ctx, cli, nsName)).To(gomega.Succeed())
-}
-
-func getTimeout(key string, fallback time.Duration) time.Duration {
-	if value, ok := os.LookupEnv(key); ok {
-		if parsed, err := time.ParseDuration(value); err == nil {
-			return parsed
-		}
-	}
-	return fallback
+	gomega.Expect(testutils.DeleteInferenceObjectiveResources(testConfig)).To(gomega.Succeed())
 }
 
 var (
-	existsTimeout     = getTimeout("EXISTS_TIMEOUT", defaultExistsTimeout)
-	readyTimeout      = getTimeout("READY_TIMEOUT", defaultReadyTimeout)
-	modelReadyTimeout = getTimeout("MODEL_READY_TIMEOUT", defaultModelReadyTimeout)
-	curlTimeout       = getTimeout("CURL_TIMEOUT", defaultCurlTimeout)
-	interval          = defaultInterval
-	curlInterval      = defaultCurlInterval
+	curlTimeout  = env.GetEnvDuration("CURL_TIMEOUT", defaultCurlTimeout, ginkgo.GinkgoLogr)
+	curlInterval = defaultCurlInterval
 )
 
-func createNamespace(k8sClient client.Client, ns string) {
-	ginkgo.By("Creating e2e namespace: " + ns)
+func createNamespace(testConfig *testutils.TestConfig) {
+	ginkgo.By("Creating e2e namespace: " + testConfig.NsName)
 	obj := &corev1.Namespace{
 		ObjectMeta: v1.ObjectMeta{
-			Name: ns,
+			Name: testConfig.NsName,
 		},
 	}
-	err := k8sClient.Create(ctx, obj)
+	err := testConfig.K8sClient.Create(testConfig.Context, obj)
 	gomega.Expect(err).NotTo(gomega.HaveOccurred(), "Failed to create e2e test namespace")
 }
 
 // namespaceExists ensures that a specified namespace exists and is ready for use.
-func namespaceExists(k8sClient client.Client, ns string) {
-	ginkgo.By("Ensuring namespace exists: " + ns)
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Name: ns}, &corev1.Namespace{})
-	}, existsTimeout, interval)
+func namespaceExists(testConfig *testutils.TestConfig) {
+	ginkgo.By("Ensuring namespace exists: " + testConfig.NsName)
+	testutils.EventuallyExists(testConfig, func() error {
+		return testConfig.K8sClient.Get(testConfig.Context,
+			types.NamespacedName{Name: testConfig.NsName}, &corev1.Namespace{})
+	})
 }
 
 // readModelServerManifestPath reads from env var the absolute filepath to model server deployment for testing.
@@ -275,57 +237,39 @@ func readModelServerManifestPath() string {
 
 func getYamlsFromModelServerManifest(modelServerManifestPath string) []string {
 	ginkgo.By("Ensuring the model server manifest points to an existing file")
-	modelServerManifestArray := readYaml(modelServerManifestPath)
+	modelServerManifestArray := testutils.ReadYaml(modelServerManifestPath)
 	gomega.Expect(modelServerManifestArray).NotTo(gomega.BeEmpty())
 	return modelServerManifestArray
 }
 
 // createCRDs creates the Inference Extension CRDs used for testing.
-func createCRDs(k8sClient client.Client, crds map[string]string) {
-	for name, path := range crds {
+func createCRDs(testConfig *testutils.TestConfig, crds map[string]string) {
+	for _, path := range crds {
 		ginkgo.By("Creating CRD resource from manifest: " + path)
-		applyYAMLFile(k8sClient, path)
-
-		// Wait for the CRD to exist.
-		crd := &apiextv1.CustomResourceDefinition{}
-		testutils.EventuallyExists(ctx, func() error {
-			return k8sClient.Get(ctx, types.NamespacedName{Name: name}, crd)
-		}, existsTimeout, interval)
-
-		// Wait for the CRD to be established.
-		testutils.CRDEstablished(ctx, k8sClient, crd, readyTimeout, interval)
+		testutils.ApplyYAMLFile(testConfig, path)
 	}
 }
 
 // createClient creates the client pod used for testing from the given filePath.
-func createClient(k8sClient client.Client, filePath string) {
+func createClient(testConfig *testutils.TestConfig, filePath string) {
 	ginkgo.By("Creating client resources from manifest: " + filePath)
-	applyYAMLFile(k8sClient, filePath)
-
-	// Wait for the pod to exist.
-	pod := &corev1.Pod{}
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: "curl"}, pod)
-	}, existsTimeout, interval)
-
-	// Wait for the pod to be ready.
-	testutils.PodReady(ctx, k8sClient, pod, readyTimeout, interval)
+	testutils.ApplyYAMLFile(testConfig, filePath)
 }
 
 // createMetricsRbac creates the metrics RBAC resources from the manifest file.
-func createMetricsRbac(k8sClient client.Client, filePath string) {
-	inManifests := readYaml(filePath)
+func createMetricsRbac(testConfig *testutils.TestConfig, filePath string) {
+	inManifests := testutils.ReadYaml(filePath)
 	ginkgo.By("Replacing placeholder namespace with E2E_NS environment variable")
 	outManifests := []string{}
 	for _, m := range inManifests {
-		outManifests = append(outManifests, strings.ReplaceAll(m, "$E2E_NS", nsName))
+		outManifests = append(outManifests, strings.ReplaceAll(m, "$E2E_NS", testConfig.NsName))
 	}
 	ginkgo.By("Creating RBAC resources for scraping metrics from manifest: " + filePath)
-	createObjsFromYaml(k8sClient, outManifests)
+	testutils.CreateObjsFromYaml(testConfig, outManifests)
 
 	// wait for sa token to exist
-	testutils.EventuallyExists(ctx, func() error {
-		token, err := getMetricsReaderToken(k8sClient)
+	testutils.EventuallyExists(testConfig, func() error {
+		token, err := getMetricsReaderToken(testConfig.K8sClient)
 		if err != nil {
 			return err
 		}
@@ -333,30 +277,21 @@ func createMetricsRbac(k8sClient client.Client, filePath string) {
 			return errors.New("failed to get metrics reader token")
 		}
 		return nil
-	}, existsTimeout, interval)
+	})
 }
 
 // createModelServer creates the model server resources used for testing from the given filePaths.
-func createModelServer(k8sClient client.Client, modelServerManifestArray []string) {
-	createObjsFromYaml(k8sClient, modelServerManifestArray)
-
-	// Wait for the deployment to exist.
-	deploy := &appsv1.Deployment{}
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: modelServerName}, deploy)
-	}, existsTimeout, interval)
-
-	// Wait for the deployment to be available.
-	testutils.DeploymentAvailable(ctx, k8sClient, deploy, modelReadyTimeout, interval)
+func createModelServer(testConfig *testutils.TestConfig, modelServerManifestArray []string) {
+	testutils.CreateObjsFromYaml(testConfig, modelServerManifestArray)
 }
 
 // createHfSecret read HF_TOKEN from env var and creates a secret that contains the access token.
-func createHfSecret(k8sClient client.Client, secretPath string) {
+func createHfSecret(testConfig *testutils.TestConfig, secretPath string) {
 	ginkgo.By("Ensuring the HF_TOKEN environment variable is set")
 	token := os.Getenv("HF_TOKEN")
 	gomega.Expect(token).NotTo(gomega.BeEmpty(), "HF_TOKEN is not set")
 
-	inManifests := readYaml(secretPath)
+	inManifests := testutils.ReadYaml(secretPath)
 	ginkgo.By("Replacing placeholder secret data with HF_TOKEN environment variable")
 	outManifests := []string{}
 	for _, m := range inManifests {
@@ -364,152 +299,49 @@ func createHfSecret(k8sClient client.Client, secretPath string) {
 	}
 
 	ginkgo.By("Creating model server secret resource")
-	createObjsFromYaml(k8sClient, outManifests)
-
-	// Wait for the secret to exist before proceeding with test.
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: "hf-token"}, &corev1.Secret{})
-	}, existsTimeout, interval)
+	testutils.CreateObjsFromYaml(testConfig, outManifests)
 }
 
 // createEnvoy creates the envoy proxy resources used for testing from the given filePath.
-func createEnvoy(k8sClient client.Client, filePath string) {
-	inManifests := readYaml(filePath)
+func createEnvoy(testConfig *testutils.TestConfig, filePath string) {
+	inManifests := testutils.ReadYaml(filePath)
 	ginkgo.By("Replacing placeholder namespace with E2E_NS environment variable")
 	outManifests := []string{}
 	for _, m := range inManifests {
-		outManifests = append(outManifests, strings.ReplaceAll(m, "$E2E_NS", nsName))
+		outManifests = append(outManifests, strings.ReplaceAll(m, "$E2E_NS", testConfig.NsName))
 	}
 
 	ginkgo.By("Creating envoy proxy resources from manifest: " + filePath)
-	createObjsFromYaml(k8sClient, outManifests)
-
-	// Wait for the configmap to exist before proceeding with test.
-	cfgMap := &corev1.ConfigMap{}
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: envoyName}, cfgMap)
-	}, existsTimeout, interval)
-
-	// Wait for the deployment to exist.
-	deploy := &appsv1.Deployment{}
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: envoyName}, deploy)
-	}, existsTimeout, interval)
-
-	// Wait for the deployment to be available.
-	testutils.DeploymentAvailable(ctx, k8sClient, deploy, readyTimeout, interval)
-
-	// Wait for the service to exist.
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: envoyName}, &corev1.Service{})
-	}, existsTimeout, interval)
+	testutils.CreateObjsFromYaml(testConfig, outManifests)
 }
 
 // createInferExt creates the inference extension resources used for testing from the given filePath.
-func createInferExt(k8sClient client.Client, filePath string) {
-	inManifests := readYaml(filePath)
+func createInferExt(testConfig *testutils.TestConfig, filePath string) {
+	inManifests := testutils.ReadYaml(filePath)
 	ginkgo.By("Replacing placeholders with environment variables")
 	outManifests := []string{}
+	replacer := strings.NewReplacer(
+		"$E2E_NS", testConfig.NsName,
+		"$E2E_IMAGE", e2eImage,
+	)
 	for _, manifest := range inManifests {
-		replacer := strings.NewReplacer(
-			"$E2E_NS", nsName,
-			"$E2E_IMAGE", e2eImage,
-		)
 		outManifests = append(outManifests, replacer.Replace(manifest))
 	}
 
 	ginkgo.By("Creating inference extension resources from manifest: " + filePath)
-	createObjsFromYaml(k8sClient, outManifests)
-
-	// Wait for the serviceaccount to exist.
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: inferExtName}, &corev1.ServiceAccount{})
-	}, existsTimeout, interval)
-
-	// Wait for the role to exist.
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: "pod-read"}, &rbacv1.Role{})
-	}, existsTimeout, interval)
-
-	// Wait for the rolebinding to exist.
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: "pod-read-binding"}, &rbacv1.RoleBinding{})
-	}, existsTimeout, interval)
-
-	// Wait for the clusterrole to exist.
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Name: "auth-reviewer"}, &rbacv1.ClusterRole{})
-	}, existsTimeout, interval)
-
-	// Wait for the clusterrolebinding to exist.
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Name: "auth-reviewer-binding"}, &rbacv1.ClusterRoleBinding{})
-	}, existsTimeout, interval)
+	testutils.CreateObjsFromYaml(testConfig, outManifests)
 
 	// Wait for the deployment to exist.
-	deploy := &appsv1.Deployment{}
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: inferExtName}, deploy)
-	}, existsTimeout, interval)
-
+	deploy := &appsv1.Deployment{
+		ObjectMeta: v1.ObjectMeta{
+			Name:      inferExtName,
+			Namespace: testConfig.NsName,
+		},
+	}
 	if leaderElectionEnabled {
 		// With leader election enabled, only 1 replica will be "Ready" at any given time (the leader).
-		testutils.DeploymentReadyReplicas(ctx, k8sClient, deploy, 1, modelReadyTimeout, interval)
+		testutils.DeploymentReadyReplicas(testConfig, deploy, 1)
 	} else {
-		testutils.DeploymentAvailable(ctx, k8sClient, deploy, modelReadyTimeout, interval)
-	}
-
-	// Wait for the service to exist.
-	testutils.EventuallyExists(ctx, func() error {
-		return k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: inferExtName}, &corev1.Service{})
-	}, existsTimeout, interval)
-}
-
-// applyYAMLFile reads a file containing YAML (possibly multiple docs)
-// and applies each object to the cluster.
-func applyYAMLFile(k8sClient client.Client, filePath string) {
-	// Create the resources from the manifest file
-	createObjsFromYaml(k8sClient, readYaml(filePath))
-}
-
-func readYaml(filePath string) []string {
-	ginkgo.By("Reading YAML file: " + filePath)
-	yamlBytes, err := os.ReadFile(filePath)
-	gomega.Expect(err).NotTo(gomega.HaveOccurred())
-
-	// Split multiple docs, if needed
-	return strings.Split(string(yamlBytes), "\n---")
-}
-
-func createObjsFromYaml(k8sClient client.Client, docs []string) {
-	// For each doc, decode and create
-	decoder := serializer.NewCodecFactory(scheme).UniversalDeserializer()
-	for _, doc := range docs {
-		trimmed := strings.TrimSpace(doc)
-		if trimmed == "" {
-			continue
-		}
-		// Decode into a runtime.Object
-		obj, gvk, decodeErr := decoder.Decode([]byte(trimmed), nil, nil)
-		gomega.Expect(decodeErr).NotTo(gomega.HaveOccurred(),
-			"Failed to decode YAML document to a Kubernetes object")
-
-		ginkgo.By(fmt.Sprintf("Decoded GVK: %s", gvk))
-
-		unstrObj, ok := obj.(*unstructured.Unstructured)
-		if !ok {
-			// Fallback if it's a typed object
-			unstrObj = &unstructured.Unstructured{}
-			// Convert typed to unstructured
-			err := scheme.Convert(obj, unstrObj, nil)
-			gomega.Expect(err).NotTo(gomega.HaveOccurred())
-		}
-
-		unstrObj.SetNamespace(nsName)
-
-		// Create the object
-		err := k8sClient.Create(ctx, unstrObj)
-		gomega.Expect(err).NotTo(gomega.HaveOccurred(),
-			"Failed to create object from YAML")
+		testutils.DeploymentAvailable(testConfig, deploy)
 	}
 }
diff --git a/test/e2e/epp/e2e_test.go b/test/e2e/epp/e2e_test.go
index e01240d..c3ff49e 100644
--- a/test/e2e/epp/e2e_test.go
+++ b/test/e2e/epp/e2e_test.go
@@ -43,23 +43,23 @@ var _ = ginkgo.Describe("InferencePool", func() {
 	var infObjective *v1alpha2.InferenceObjective
 	ginkgo.BeforeEach(func() {
 		ginkgo.By("Waiting for the namespace to exist.")
-		namespaceExists(cli, nsName)
+		namespaceExists(testConfig)
 
 		ginkgo.By("Creating an InferenceObjective resource")
-		infObjective = newInferenceObjective(nsName)
-		gomega.Expect(cli.Create(ctx, infObjective)).To(gomega.Succeed())
+		infObjective = newInferenceObjective(testConfig.NsName)
+		gomega.Expect(testConfig.K8sClient.Create(testConfig.Context, infObjective)).To(gomega.Succeed())
 
 		ginkgo.By("Ensuring the InferenceObjective resource exists in the namespace")
 		gomega.Eventually(func() error {
-			return cli.Get(ctx, types.NamespacedName{Namespace: infObjective.Namespace, Name: infObjective.Name}, infObjective)
-		}, existsTimeout, interval).Should(gomega.Succeed())
+			return testConfig.K8sClient.Get(testConfig.Context, types.NamespacedName{Namespace: infObjective.Namespace, Name: infObjective.Name}, infObjective)
+		}, testConfig.ExistsTimeout, testConfig.Interval).Should(gomega.Succeed())
 	})
 
 	ginkgo.AfterEach(func() {
 		ginkgo.By("Deleting the InferenceObjective test resource.")
 		cleanupInferModelResources()
 		gomega.Eventually(func() error {
-			err := cli.Get(ctx, types.NamespacedName{Namespace: infObjective.Namespace, Name: infObjective.Name}, infObjective)
+			err := testConfig.K8sClient.Get(testConfig.Context, types.NamespacedName{Namespace: infObjective.Namespace, Name: infObjective.Name}, infObjective)
 			if err == nil {
 				return errors.New("InferenceObjective resource still exists")
 			}
@@ -67,7 +67,7 @@ var _ = ginkgo.Describe("InferencePool", func() {
 				return nil
 			}
 			return nil
-		}, existsTimeout, interval).Should(gomega.Succeed())
+		}, testConfig.ExistsTimeout, testConfig.Interval).Should(gomega.Succeed())
 	})
 
 	ginkgo.When("The Inference Extension is running", func() {
@@ -89,7 +89,7 @@ var _ = ginkgo.Describe("InferencePool", func() {
 			ginkgo.By("Verifying that exactly one EPP pod is ready")
 			gomega.Eventually(func(g gomega.Gomega) {
 				podList := &corev1.PodList{}
-				err := cli.List(ctx, podList, client.InNamespace(nsName), client.MatchingLabels{"app": inferExtName})
+				err := testConfig.K8sClient.List(testConfig.Context, podList, client.InNamespace(testConfig.NsName), client.MatchingLabels{"app": inferExtName})
 				g.Expect(err).NotTo(gomega.HaveOccurred())
 
 				// The deployment should have 3 replicas for leader election.
@@ -104,7 +104,7 @@ var _ = ginkgo.Describe("InferencePool", func() {
 					}
 				}
 				g.Expect(readyPods).To(gomega.Equal(1), "Expected exactly one pod to be ready")
-			}, readyTimeout, interval).Should(gomega.Succeed())
+			}, testConfig.ReadyTimeout, testConfig.Interval).Should(gomega.Succeed())
 		})
 
 		ginkgo.It("Should successfully failover and serve traffic after the leader pod is deleted", func() {
@@ -121,26 +121,26 @@ var _ = ginkgo.Describe("InferencePool", func() {
 			ginkgo.By("Found initial leader pod: " + oldLeaderPod.Name)
 
 			ginkgo.By(fmt.Sprintf("Deleting leader pod %s to trigger failover", oldLeaderPod.Name))
-			gomega.Expect(cli.Delete(ctx, oldLeaderPod)).To(gomega.Succeed())
+			gomega.Expect(testConfig.K8sClient.Delete(testConfig.Context, oldLeaderPod)).To(gomega.Succeed())
 
 			ginkgo.By("STEP 3: Waiting for a new leader to be elected")
 			// The deployment controller will create a new pod. We need to wait for the total number of pods
 			// to be back to 3, and for one of the other pods to become the new leader.
 			deploy := &appsv1.Deployment{}
 			gomega.Eventually(func() error {
-				return cli.Get(ctx, types.NamespacedName{Namespace: nsName, Name: inferExtName}, deploy)
-			}, existsTimeout, interval).Should(gomega.Succeed())
+				return testConfig.K8sClient.Get(testConfig.Context, types.NamespacedName{Namespace: testConfig.NsName, Name: inferExtName}, deploy)
+			}, testConfig.ExistsTimeout, testConfig.Interval).Should(gomega.Succeed())
 
 			// Wait for one replica to become ready again.
-			testutils.DeploymentReadyReplicas(ctx, cli, deploy, 1, readyTimeout, interval)
+			testutils.DeploymentReadyReplicas(testConfig, deploy, 1)
 
 			// Also wait for the total number of replicas to be back to 3.
 			gomega.Eventually(func(g gomega.Gomega) {
 				d := &appsv1.Deployment{}
-				err := cli.Get(ctx, types.NamespacedName{Namespace: nsName, Name: inferExtName}, d)
+				err := testConfig.K8sClient.Get(testConfig.Context, types.NamespacedName{Namespace: testConfig.NsName, Name: inferExtName}, d)
 				g.Expect(err).NotTo(gomega.HaveOccurred())
 				g.Expect(d.Status.Replicas).To(gomega.Equal(int32(3)), "Deployment should have 3 replicas")
-			}, readyTimeout, interval).Should(gomega.Succeed())
+			}, testConfig.ReadyTimeout, testConfig.Interval).Should(gomega.Succeed())
 
 			ginkgo.By("STEP 4: Verifying a new, different leader is elected")
 			var newLeaderPod *corev1.Pod
@@ -152,7 +152,7 @@ var _ = ginkgo.Describe("InferencePool", func() {
 				// This guards against a race condition where we might find the old leader
 				// before its status is updated to NotReady.
 				g.Expect(newLeaderPod.Name).NotTo(gomega.Equal(oldLeaderPod.Name), "The new leader should not be the same as the old deleted leader")
-			}, readyTimeout, interval).Should(gomega.Succeed())
+			}, testConfig.ReadyTimeout, testConfig.Interval).Should(gomega.Succeed())
 			ginkgo.By("Found new leader pod: " + newLeaderPod.Name)
 
 			ginkgo.By("STEP 5: Verifying the new leader is working correctly after failover")
@@ -207,11 +207,11 @@ func verifyTrafficRouting() {
 		// Ensure the expected responses include the InferenceObjective target model names.
 		var expected []string
 		expected = append(expected, targetModelName)
-		curlCmd := getCurlCommand(envoyName, nsName, envoyPort, modelName, curlTimeout, t.api, t.promptOrMessages, false)
+		curlCmd := getCurlCommand(envoyName, testConfig.NsName, envoyPort, modelName, curlTimeout, t.api, t.promptOrMessages, false)
 
 		actual := make(map[string]int)
 		gomega.Eventually(func() error {
-			resp, err := testutils.ExecCommandInPod(ctx, cfg, scheme, kubeCli, nsName, "curl", "curl", curlCmd)
+			resp, err := testutils.ExecCommandInPod(testConfig, "curl", "curl", curlCmd)
 			if err != nil {
 				return err
 			}
@@ -232,7 +232,7 @@ func verifyTrafficRouting() {
 				return fmt.Errorf("actual (%v) != expected (%v); resp=%q", got, expected, resp)
 			}
 			return nil
-		}, readyTimeout, curlInterval).Should(gomega.Succeed())
+		}, testConfig.ReadyTimeout, curlInterval).Should(gomega.Succeed())
 	}
 }
 
@@ -241,37 +241,37 @@ func verifyMetrics() {
 	ginkgo.By("Verifying metrics exposure")
 	// Define the metrics we expect to see
 	expectedMetrics := []string{
-		"inference_model_request_total",
-		"inference_model_request_error_total",
-		"inference_model_request_duration_seconds",
+		"inference_objective_request_total",
+		"inference_objective_request_error_total",
+		"inference_objective_request_duration_seconds",
 		// TODO: normalized_time_per_output_token_seconds is not actually recorded yet
 		// "normalized_time_per_output_token_seconds",
-		"inference_model_request_sizes",
-		"inference_model_response_sizes",
-		"inference_model_input_tokens",
-		"inference_model_output_tokens",
+		"inference_objective_request_sizes",
+		"inference_objective_response_sizes",
+		"inference_objective_input_tokens",
+		"inference_objective_output_tokens",
 		"inference_pool_average_kv_cache_utilization",
 		"inference_pool_average_queue_size",
 		"inference_pool_per_pod_queue_size",
-		"inference_model_running_requests",
+		"inference_objective_running_requests",
 		"inference_pool_ready_pods",
 		"inference_extension_info",
 	}
 
 	// Generate traffic by sending requests through the inference extension
 	ginkgo.By("Generating traffic through the inference extension")
-	curlCmd := getCurlCommand(envoyName, nsName, envoyPort, modelName, curlTimeout, "/completions", "Write as if you were a critic: San Francisco", true)
+	curlCmd := getCurlCommand(envoyName, testConfig.NsName, envoyPort, modelName, curlTimeout, "/completions", "Write as if you were a critic: San Francisco", true)
 
 	// Run the curl command multiple times to generate some metrics data
 	for i := 0; i < 5; i++ {
-		_, err := testutils.ExecCommandInPod(ctx, cfg, scheme, kubeCli, nsName, "curl", "curl", curlCmd)
+		_, err := testutils.ExecCommandInPod(testConfig, "curl", "curl", curlCmd)
 		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	}
 
 	// modify the curl command to generate some error metrics
 	curlCmd[len(curlCmd)-1] = "invalid input"
 	for i := 0; i < 5; i++ {
-		_, err := testutils.ExecCommandInPod(ctx, cfg, scheme, kubeCli, nsName, "curl", "curl", curlCmd)
+		_, err := testutils.ExecCommandInPod(testConfig, "curl", "curl", curlCmd)
 		gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	}
 
@@ -282,11 +282,11 @@ func verifyMetrics() {
 	// Get the authorization token for reading metrics
 	token := ""
 	gomega.Eventually(func(g gomega.Gomega) {
-		t, err := getMetricsReaderToken(cli)
+		t, err := getMetricsReaderToken(testConfig.K8sClient)
 		g.Expect(err).NotTo(gomega.HaveOccurred())
 		g.Expect(t).NotTo(gomega.BeEmpty())
 		token = t
-	}, existsTimeout, interval).Should(gomega.Succeed())
+	}, testConfig.ExistsTimeout, testConfig.Interval).Should(gomega.Succeed())
 
 	// Construct the metric scraping curl command using Pod IP
 	metricScrapeCmd := getMetricsScrapeCommand(podIP, token)
@@ -294,7 +294,7 @@ func verifyMetrics() {
 	ginkgo.By("Verifying that all expected metrics are present.")
 	gomega.Eventually(func() error {
 		// Execute the metrics scrape command inside the curl pod
-		resp, err := testutils.ExecCommandInPod(ctx, cfg, scheme, kubeCli, nsName, "curl", "curl", metricScrapeCmd)
+		resp, err := testutils.ExecCommandInPod(testConfig, "curl", "curl", metricScrapeCmd)
 		if err != nil {
 			return err
 		}
@@ -309,12 +309,12 @@ func verifyMetrics() {
 			}
 		}
 		return nil
-	}, readyTimeout, curlInterval).Should(gomega.Succeed())
+	}, testConfig.ReadyTimeout, curlInterval).Should(gomega.Succeed())
 }
 
 func getMetricsReaderToken(k8sClient client.Client) (string, error) {
 	secret := &corev1.Secret{}
-	err := k8sClient.Get(ctx, types.NamespacedName{Namespace: nsName, Name: metricsReaderSecretName}, secret)
+	err := k8sClient.Get(testConfig.Context, types.NamespacedName{Namespace: testConfig.NsName, Name: metricsReaderSecretName}, secret)
 	if err != nil {
 		return "", err
 	}
@@ -327,7 +327,7 @@ func findReadyPod() *corev1.Pod {
 	var readyPod *corev1.Pod
 	gomega.Eventually(func(g gomega.Gomega) {
 		podList := &corev1.PodList{}
-		err := cli.List(ctx, podList, client.InNamespace(nsName), client.MatchingLabels{"app": inferExtName})
+		err := testConfig.K8sClient.List(testConfig.Context, podList, client.InNamespace(testConfig.NsName), client.MatchingLabels{"app": inferExtName})
 		g.Expect(err).NotTo(gomega.HaveOccurred())
 
 		foundReadyPod := false
@@ -346,7 +346,7 @@ func findReadyPod() *corev1.Pod {
 			}
 		}
 		g.Expect(foundReadyPod).To(gomega.BeTrue(), "No ready EPP pod found")
-	}, readyTimeout, interval).Should(gomega.Succeed())
+	}, testConfig.ReadyTimeout, testConfig.Interval).Should(gomega.Succeed())
 	return readyPod
 }
 
diff --git a/test/integration/epp/hermetic_test.go b/test/integration/epp/hermetic_test.go
index 48cf889..3dc42f8 100644
--- a/test/integration/epp/hermetic_test.go
+++ b/test/integration/epp/hermetic_test.go
@@ -76,6 +76,7 @@ import (
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/scorer"
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/server"
 	logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
+	requtil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/request"
 	epptestutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/testing"
 	integrationutils "sigs.k8s.io/gateway-api-inference-extension/test/integration"
 )
@@ -132,11 +133,10 @@ func labelsToString(labels []label) string {
 
 func inferenceObjectiveRequestTotal(labels []label) string {
 	return fmt.Sprintf(`
-		# HELP inference_model_request_total [ALPHA] Counter of inference model requests broken out for each model and target model.
-		# TYPE inference_model_request_total counter
-		inference_model_request_total{%s} 1
-		`, labelsToString(labels),
-	)
+		# HELP inference_objective_request_total [ALPHA] Counter of inference objective requests broken out for each model and target model.
+		# TYPE inference_objective_request_total counter
+		inference_objective_request_total{%s} 1
+		`, labelsToString(labels))
 }
 
 func inferencePoolReadyPods(v int, labels []label) string {
@@ -144,8 +144,7 @@ func inferencePoolReadyPods(v int, labels []label) string {
 		# HELP inference_pool_ready_pods [ALPHA] The number of ready pods in the inference server pool.
 		# TYPE inference_pool_ready_pods gauge
 		inference_pool_ready_pods{%s} %d
-		`, labelsToString(labels), v,
-	)
+		`, labelsToString(labels), v)
 }
 
 func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
@@ -169,7 +168,7 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 				podState{index: 2, queueSize: 10, kvCacheUsage: 0.2},
 			),
 			wantMetrics: map[string]string{
-				"inference_model_request_total": inferenceObjectiveRequestTotal([]label{
+				"inference_objective_request_total": inferenceObjectiveRequestTotal([]label{
 					{"model_name", modelMyModel},
 					{"target_model_name", modelMyModelTarget},
 				}),
@@ -187,6 +186,12 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 						RawValue: []byte("mom"),
 					},
 				},
+				&configPb.HeaderValueOption{
+					Header: &configPb.HeaderValue{
+						Key:      requtil.RequestIdHeaderKey,
+						RawValue: []byte("test-request-id"),
+					},
+				},
 			),
 		},
 		{
@@ -235,7 +240,7 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 			),
 
 			wantMetrics: map[string]string{
-				"inference_model_request_total": inferenceObjectiveRequestTotal([]label{
+				"inference_objective_request_total": inferenceObjectiveRequestTotal([]label{
 					{"model_name", modelSQLLora},
 					{"target_model_name", modelSQLLoraTarget},
 				}),
@@ -250,6 +255,12 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 						RawValue: []byte("mom"),
 					},
 				},
+				&configPb.HeaderValueOption{
+					Header: &configPb.HeaderValue{
+						Key:      requtil.RequestIdHeaderKey,
+						RawValue: []byte("test-request-id"),
+					},
+				},
 			),
 		},
 		{
@@ -264,7 +275,7 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 				podState{index: 2, queueSize: 10, kvCacheUsage: 0.3, activeModels: []string{"foo"}},
 			),
 			wantMetrics: map[string]string{
-				"inference_model_request_total": inferenceObjectiveRequestTotal([]label{
+				"inference_objective_request_total": inferenceObjectiveRequestTotal([]label{
 					{"model_name", modelSQLLora},
 					{"target_model_name", modelSQLLoraTarget},
 				}),
@@ -279,6 +290,12 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 						RawValue: []byte("mom"),
 					},
 				},
+				&configPb.HeaderValueOption{
+					Header: &configPb.HeaderValue{
+						Key:      requtil.RequestIdHeaderKey,
+						RawValue: []byte("test-request-id"),
+					},
+				},
 			),
 		},
 		{
@@ -293,7 +310,7 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 				podState{index: 2, queueSize: 10, kvCacheUsage: 0.9, activeModels: []string{"foo"}},
 			),
 			wantMetrics: map[string]string{
-				"inference_model_request_total": inferenceObjectiveRequestTotal([]label{
+				"inference_objective_request_total": inferenceObjectiveRequestTotal([]label{
 					{"model_name", modelSQLLora},
 					{"target_model_name", modelSQLLoraTarget},
 				}),
@@ -308,6 +325,12 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 						RawValue: []byte("mom"),
 					},
 				},
+				&configPb.HeaderValueOption{
+					Header: &configPb.HeaderValue{
+						Key:      requtil.RequestIdHeaderKey,
+						RawValue: []byte("test-request-id"),
+					},
+				},
 			),
 		},
 		{
@@ -330,12 +353,15 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 										Key:   metadata.ModelNameRewriteKey,
 										Value: modelSheddableTarget,
 									},
+									{
+										Key:   requtil.RequestIdHeaderKey,
+										Value: "test-request-id",
+									},
 								},
 							},
 						},
 					},
-				},
-				{
+				}, {
 					Request: &extProcPb.ProcessingRequest_RequestBody{
 						RequestBody: &extProcPb.HttpBody{Body: []byte("{\"max_tokens\":100,\"model\":\"sql-lo"), EndOfStream: false},
 					},
@@ -353,7 +379,7 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 				podState{index: 2, queueSize: 10, kvCacheUsage: 0.9, activeModels: []string{"foo", modelSheddableTarget}},
 			),
 			wantMetrics: map[string]string{
-				"inference_model_request_total": inferenceObjectiveRequestTotal([]label{
+				"inference_objective_request_total": inferenceObjectiveRequestTotal([]label{
 					{"model_name", modelSheddable},
 					{"target_model_name", modelSheddableTarget},
 				}),
@@ -368,6 +394,12 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 						RawValue: []byte("mom"),
 					},
 				},
+				&configPb.HeaderValueOption{
+					Header: &configPb.HeaderValue{
+						Key:      requtil.RequestIdHeaderKey,
+						RawValue: []byte("test-request-id"),
+					},
+				},
 			),
 		},
 		{
@@ -394,6 +426,10 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 										Key:   metadata.ModelNameRewriteKey,
 										Value: modelDirect,
 									},
+									{
+										Key:   requtil.RequestIdHeaderKey,
+										Value: "test-request-id",
+									},
 								},
 							},
 						},
@@ -417,7 +453,7 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 				podState{index: 2, queueSize: 10, kvCacheUsage: 0.9, activeModels: []string{"foo", modelSheddableTarget}},
 			),
 			wantMetrics: map[string]string{
-				"inference_model_request_total": inferenceObjectiveRequestTotal([]label{
+				"inference_objective_request_total": inferenceObjectiveRequestTotal([]label{
 					{"model_name", modelDirect},
 					{"target_model_name", modelDirect},
 				}),
@@ -432,6 +468,12 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 						RawValue: []byte("mom"),
 					},
 				},
+				&configPb.HeaderValueOption{
+					Header: &configPb.HeaderValue{
+						Key:      requtil.RequestIdHeaderKey,
+						RawValue: []byte("test-request-id"),
+					},
+				},
 			),
 		},
 		// Response flow tests
@@ -660,32 +702,31 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 					},
 				},
 			},
-			wantErr: false,
-			wantMetrics: map[string]string{`inference_model_input_tokens`: `
-					# HELP inference_model_input_tokens [ALPHA] Inference model input token count distribution for requests in each model.
-					# TYPE inference_model_input_tokens histogram
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="1"} 0
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="8"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="16"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="32"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="64"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="128"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="256"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="512"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="1024"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="2048"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="4096"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="8192"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="16384"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="32778"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="65536"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="131072"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="262144"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="524288"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="1.048576e+06"} 1
-		            inference_model_input_tokens_bucket{model_name="",target_model_name="",le="+Inf"} 1
-		            inference_model_input_tokens_sum{model_name="",target_model_name=""} 7
-		            inference_model_input_tokens_count{model_name="",target_model_name=""} 1
+			wantMetrics: map[string]string{`inference_objective_input_tokens`: `
+					# HELP inference_objective_input_tokens [ALPHA] Inference objective input token count distribution for requests in each model.
+					# TYPE inference_objective_input_tokens histogram
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="1"} 0
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="8"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="16"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="32"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="64"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="128"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="256"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="512"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="1024"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="2048"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="4096"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="8192"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="16384"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="32778"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="65536"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="131072"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="262144"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="524288"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="1.048576e+06"} 1
+		            inference_objective_input_tokens_bucket{model_name="",target_model_name="",le="+Inf"} 1
+		            inference_objective_input_tokens_sum{model_name="",target_model_name=""} 7
+		            inference_objective_input_tokens_count{model_name="",target_model_name=""} 1
 					`},
 			wantResponses: []*extProcPb.ProcessingResponse{
 				integrationutils.NewResponseHeaders(
@@ -763,7 +804,7 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 			),
 
 			wantMetrics: map[string]string{
-				"inference_model_request_total": inferenceObjectiveRequestTotal([]label{
+				"inference_objective_request_total": inferenceObjectiveRequestTotal([]label{
 					{"model_name", modelSQLLora},
 					{"target_model_name", modelSQLLoraTarget},
 				}),
@@ -778,6 +819,12 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 						RawValue: []byte("mom"),
 					},
 				},
+				&configPb.HeaderValueOption{
+					Header: &configPb.HeaderValue{
+						Key:      requtil.RequestIdHeaderKey,
+						RawValue: []byte("test-request-id"),
+					},
+				},
 			),
 		},
 		{
@@ -796,7 +843,7 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 			),
 
 			wantMetrics: map[string]string{
-				"inference_model_request_total": inferenceObjectiveRequestTotal([]label{
+				"inference_objective_request_total": inferenceObjectiveRequestTotal([]label{
 					{"model_name", modelSQLLora},
 					{"target_model_name", modelSQLLoraTarget},
 				}),
@@ -811,6 +858,12 @@ func TestFullDuplexStreamed_KubeInferenceObjectiveRequest(t *testing.T) {
 						RawValue: []byte("mom"),
 					},
 				},
+				&configPb.HeaderValueOption{
+					Header: &configPb.HeaderValue{
+						Key:      requtil.RequestIdHeaderKey,
+						RawValue: []byte("test-request-id"),
+					},
+				},
 			),
 		},
 		{
@@ -1104,7 +1157,7 @@ func BeforeSuite() func() {
 
 	kvCacheUtilizationScorer := scorer.NewKVCacheUtilizationScorer()
 	queueingScorer := scorer.NewQueueScorer()
-	prefixCacheScorer := prefix.New(prefix.DefaultConfig)
+	prefixCacheScorer := prefix.New(context.Background(), prefix.DefaultConfig)
 	loraAffinityScorer := scorer.NewLoraAffinityScorer()
 
 	defaultProfile := framework.NewSchedulerProfile().
@@ -1125,7 +1178,7 @@ func BeforeSuite() func() {
 		KVCacheUtilThreshold:      saturationdetector.DefaultKVCacheUtilThreshold,
 		MetricsStalenessThreshold: saturationdetector.DefaultMetricsStalenessThreshold,
 	}
-	detector := saturationdetector.NewDetector(sdConfig, serverRunner.Datastore, logger.WithName("saturation-detector"))
+	detector := saturationdetector.NewDetector(sdConfig, logger.WithName("saturation-detector"))
 	serverRunner.SaturationDetector = detector
 	serverRunner.Director = requestcontrol.NewDirectorWithConfig(serverRunner.Datastore, scheduler, detector, requestcontrol.NewConfig())
 	serverRunner.SecureServing = false
diff --git a/test/integration/util.go b/test/integration/util.go
index 0052449..d78b76e 100644
--- a/test/integration/util.go
+++ b/test/integration/util.go
@@ -31,6 +31,7 @@ import (
 
 	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/metadata"
 	logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
+	requtil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/request"
 )
 
 const (
@@ -130,6 +131,10 @@ func GenerateStreamedRequestSet(logger logr.Logger, prompt, model, targetModel s
 							Key:   metadata.ModelNameRewriteKey,
 							Value: targetModel,
 						},
+						{
+							Key:   requtil.RequestIdHeaderKey,
+							Value: "test-request-id",
+						},
 					},
 				},
 			},
diff --git a/test/testdata/configloader_1_test.yaml b/test/testdata/configloader_1_test.yaml
index f1f167e..db75a42 100644
--- a/test/testdata/configloader_1_test.yaml
+++ b/test/testdata/configloader_1_test.yaml
@@ -9,7 +9,7 @@ plugins:
   type: test-profile-handler
 - type: test-two
   parameters:
-    hashBlockSize: 32
+    blockSize: 32
 - name: testPicker
   type: test-picker
 
diff --git a/test/testdata/inferencepool-e2e.yaml b/test/testdata/inferencepool-e2e.yaml
index 7c546ba..77d454e 100644
--- a/test/testdata/inferencepool-e2e.yaml
+++ b/test/testdata/inferencepool-e2e.yaml
@@ -9,9 +9,12 @@ spec:
   selector:
     matchLabels:
       app: vllm-llama3-8b-instruct
-  extensionRef:
+  endpointPickerRef:
     name: vllm-llama3-8b-instruct-epp
     namespace: $E2E_NS
+    kind: Service
+    port:
+      number: 9002
 ---
 apiVersion: v1
 kind: Service
@@ -34,6 +37,87 @@ metadata:
   name: vllm-llama3-8b-instruct-epp
   namespace: $E2E_NS
 ---
+kind: Role
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: pod-read
+  namespace: $E2E_NS
+rules:
+- apiGroups: [ "inference.networking.x-k8s.io" ]
+  resources: [ "inferenceobjectives", "inferencepools" ]
+  verbs: [ "get", "watch", "list" ]
+- apiGroups: [ "inference.networking.k8s.io" ]
+  resources: [ "inferencepools" ]
+  verbs: [ "get", "watch", "list" ]
+- apiGroups: [ "" ]
+  resources: [ "pods" ]
+  verbs: [ "get", "watch", "list" ]
+---
+kind: RoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: pod-read-binding
+  namespace: $E2E_NS
+subjects:
+- kind: ServiceAccount
+  name: vllm-llama3-8b-instruct-epp
+  namespace: $E2E_NS
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: pod-read
+---
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: auth-reviewer
+rules:
+- apiGroups:
+  - authentication.k8s.io
+  resources:
+  - tokenreviews
+  verbs:
+  - create
+- apiGroups:
+  - authorization.k8s.io
+  resources:
+  - subjectaccessreviews
+  verbs:
+  - create
+---
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: auth-reviewer-binding
+subjects:
+- kind: ServiceAccount
+  name: vllm-llama3-8b-instruct-epp
+  namespace: $E2E_NS
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: auth-reviewer
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: plugins-config
+  namespace: $E2E_NS
+data:
+  default-plugins.yaml: |
+    apiVersion: inference.networking.x-k8s.io/v1alpha1
+    kind: EndpointPickerConfig
+    plugins:
+    - type: queue-scorer
+    - type: kv-cache-utilization-scorer
+    - type: prefix-cache-scorer
+    schedulingProfiles:
+    - name: default
+      plugins:
+      - pluginRef: queue-scorer
+      - pluginRef: kv-cache-utilization-scorer
+      - pluginRef: prefix-cache-scorer
+---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
@@ -97,84 +181,3 @@ spec:
       - name: plugins-config-volume
         configMap:
           name: plugins-config
----
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: plugins-config
-  namespace: $E2E_NS
-data:
-  default-plugins.yaml: |
-    apiVersion: inference.networking.x-k8s.io/v1alpha1
-    kind: EndpointPickerConfig
-    plugins:
-    - type: queue-scorer
-    - type: kv-cache-utilization-scorer
-    - type: prefix-cache-scorer
-    schedulingProfiles:
-    - name: default
-      plugins:
-      - pluginRef: queue-scorer
-      - pluginRef: kv-cache-utilization-scorer
-      - pluginRef: prefix-cache-scorer
----
-kind: Role
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: pod-read
-  namespace: $E2E_NS
-rules:
-- apiGroups: [ "inference.networking.x-k8s.io" ]
-  resources: [ "inferenceobjectives", "inferencepools" ]
-  verbs: [ "get", "watch", "list" ]
-- apiGroups: [ "inference.networking.k8s.io" ]
-  resources: [ "inferencepools" ]
-  verbs: [ "get", "watch", "list" ]
-- apiGroups: [ "" ]
-  resources: [ "pods" ]
-  verbs: [ "get", "watch", "list" ]
----
-kind: RoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: pod-read-binding
-  namespace: $E2E_NS
-subjects:
-- kind: ServiceAccount
-  name: vllm-llama3-8b-instruct-epp
-  namespace: $E2E_NS
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: Role
-  name: pod-read
----
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: auth-reviewer
-rules:
-- apiGroups:
-  - authentication.k8s.io
-  resources:
-  - tokenreviews
-  verbs:
-  - create
-- apiGroups:
-  - authorization.k8s.io
-  resources:
-  - subjectaccessreviews
-  verbs:
-  - create
----
-kind: ClusterRoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: auth-reviewer-binding
-subjects:
-- kind: ServiceAccount
-  name: vllm-llama3-8b-instruct-epp
-  namespace: $E2E_NS
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: ClusterRole
-  name: auth-reviewer
diff --git a/test/testdata/inferencepool-leader-election-e2e.yaml b/test/testdata/inferencepool-leader-election-e2e.yaml
index 413fa55..976fbbd 100644
--- a/test/testdata/inferencepool-leader-election-e2e.yaml
+++ b/test/testdata/inferencepool-leader-election-e2e.yaml
@@ -7,9 +7,12 @@ spec:
   targetPortNumber: 8000
   selector:
     app: vllm-llama3-8b-instruct
-  extensionRef:
+  endpointPickerRef:
     name: vllm-llama3-8b-instruct-epp
     namespace: $E2E_NS
+    kind: Service
+    port:
+      number: 9002
 ---
 apiVersion: v1
 kind: Service
@@ -32,91 +35,6 @@ metadata:
   name: vllm-llama3-8b-instruct-epp
   namespace: $E2E_NS
 ---
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: vllm-llama3-8b-instruct-epp
-  namespace: $E2E_NS
-  labels:
-    app: vllm-llama3-8b-instruct-epp
-spec:
-  replicas: 3
-  selector:
-    matchLabels:
-      app: vllm-llama3-8b-instruct-epp
-  template:
-    metadata:
-      labels:
-        app: vllm-llama3-8b-instruct-epp
-    spec:
-      serviceAccountName: vllm-llama3-8b-instruct-epp
-      # Conservatively, this timeout should mirror the longest grace period of the pods within the pool
-      terminationGracePeriodSeconds: 130
-      containers:
-      - name: epp
-        image: $E2E_IMAGE
-        imagePullPolicy: IfNotPresent
-        args:
-        - --pool-name
-        - "vllm-llama3-8b-instruct"
-        - --pool-namespace
-        - "$E2E_NS"
-        - --v
-        - "4"
-        - --zap-encoder
-        - "json"
-        - --grpc-port
-        - "9002"
-        - --grpc-health-port
-        - "9003"
-        - --ha-enable-leader-election
-        - "--config-file"
-        - "/config/default-plugins.yaml"
-        ports:
-        - containerPort: 9002
-        - containerPort: 9003
-        - name: metrics
-          containerPort: 9090
-        livenessProbe:
-          grpc:
-            port: 9003
-            service: liveness
-          initialDelaySeconds: 5
-          periodSeconds: 10
-        readinessProbe:
-          grpc:
-            port: 9003
-            service: readiness
-          initialDelaySeconds: 5
-          periodSeconds: 10
-        volumeMounts:
-        - name: plugins-config-volume
-          mountPath: "/config"
-      volumes:
-      - name: plugins-config-volume
-        configMap:
-          name: plugins-config
----
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: plugins-config
-  namespace: $E2E_NS
-data:
-  default-plugins.yaml: |
-    apiVersion: inference.networking.x-k8s.io/v1alpha1
-    kind: EndpointPickerConfig
-    plugins:
-    - type: queue-scorer
-    - type: kv-cache-utilization-scorer
-    - type: prefix-cache-scorer
-    schedulingProfiles:
-    - name: default
-      plugins:
-      - pluginRef: queue-scorer
-      - pluginRef: kv-cache-utilization-scorer
-      - pluginRef: prefix-cache-scorer
----
 kind: Role
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
@@ -204,3 +122,88 @@ roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
   name: auth-reviewer
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: plugins-config
+  namespace: $E2E_NS
+data:
+  default-plugins.yaml: |
+    apiVersion: inference.networking.x-k8s.io/v1alpha1
+    kind: EndpointPickerConfig
+    plugins:
+    - type: queue-scorer
+    - type: kv-cache-utilization-scorer
+    - type: prefix-cache-scorer
+    schedulingProfiles:
+    - name: default
+      plugins:
+      - pluginRef: queue-scorer
+      - pluginRef: kv-cache-utilization-scorer
+      - pluginRef: prefix-cache-scorer
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: vllm-llama3-8b-instruct-epp
+  namespace: $E2E_NS
+  labels:
+    app: vllm-llama3-8b-instruct-epp
+spec:
+  replicas: 3
+  selector:
+    matchLabels:
+      app: vllm-llama3-8b-instruct-epp
+  template:
+    metadata:
+      labels:
+        app: vllm-llama3-8b-instruct-epp
+    spec:
+      serviceAccountName: vllm-llama3-8b-instruct-epp
+      # Conservatively, this timeout should mirror the longest grace period of the pods within the pool
+      terminationGracePeriodSeconds: 130
+      containers:
+      - name: epp
+        image: $E2E_IMAGE
+        imagePullPolicy: IfNotPresent
+        args:
+        - --pool-name
+        - "vllm-llama3-8b-instruct"
+        - --pool-namespace
+        - "$E2E_NS"
+        - --v
+        - "4"
+        - --zap-encoder
+        - "json"
+        - --grpc-port
+        - "9002"
+        - --grpc-health-port
+        - "9003"
+        - --ha-enable-leader-election
+        - "--config-file"
+        - "/config/default-plugins.yaml"
+        ports:
+        - containerPort: 9002
+        - containerPort: 9003
+        - name: metrics
+          containerPort: 9090
+        livenessProbe:
+          grpc:
+            port: 9003
+            service: liveness
+          initialDelaySeconds: 5
+          periodSeconds: 10
+        readinessProbe:
+          grpc:
+            port: 9003
+            service: readiness
+          initialDelaySeconds: 5
+          periodSeconds: 10
+        volumeMounts:
+        - name: plugins-config-volume
+          mountPath: "/config"
+      volumes:
+      - name: plugins-config-volume
+        configMap:
+          name: plugins-config
diff --git a/test/testdata/inferencepool-with-model-hermetic.yaml b/test/testdata/inferencepool-with-model-hermetic.yaml
index 20fea8d..df6ae30 100644
--- a/test/testdata/inferencepool-with-model-hermetic.yaml
+++ b/test/testdata/inferencepool-with-model-hermetic.yaml
@@ -9,8 +9,11 @@ spec:
   selector:
     matchLabels:
       app: vllm-llama3-8b-instruct-pool
-  extensionRef:
+  endpointPickerRef:
     name: epp
+    kind: Service
+    port:
+      number: 9002
 ---
 apiVersion: inference.networking.x-k8s.io/v1alpha2
 kind: InferenceObjective
diff --git a/test/utils/utils.go b/test/utils/utils.go
index 8cc19b7..b65834c 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -20,6 +20,8 @@ import (
 	"bytes"
 	"context"
 	"fmt"
+	"os"
+	"strings"
 	"time"
 
 	"github.com/onsi/ginkgo/v2"
@@ -30,25 +32,84 @@ import (
 	apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/serializer"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/remotecommand"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/client/config"
 
 	v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
 	"sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
+	"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/env"
 )
 
+const (
+	// defaultExistsTimeout is the default timeout for a resource to exist in the api server.
+	defaultExistsTimeout = 30 * time.Second
+	// defaultReadyTimeout is the default timeout for a resource to report a ready state.
+	defaultReadyTimeout = 3 * time.Minute
+	// defaultModelReadyTimeout is the default timeout for the model server deployment to report a ready state.
+	defaultModelReadyTimeout = 10 * time.Minute
+	// defaultInterval is the default interval to check if a resource exists or ready conditions.
+	defaultInterval = time.Millisecond * 250
+)
+
+// TestConfig groups various fields together for use in the test helpers
+type TestConfig struct {
+	Context           context.Context
+	KubeCli           *kubernetes.Clientset
+	K8sClient         client.Client
+	RestConfig        *rest.Config
+	NsName            string
+	Scheme            *runtime.Scheme
+	ExistsTimeout     time.Duration
+	ReadyTimeout      time.Duration
+	ModelReadyTimeout time.Duration
+	Interval          time.Duration
+}
+
+// NewTestConfig creates a new TestConfig instance
+func NewTestConfig(nsName string) *TestConfig {
+	cfg := config.GetConfigOrDie()
+	gomega.Expect(cfg).NotTo(gomega.BeNil())
+
+	kubeCli, err := kubernetes.NewForConfig(cfg)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+	gomega.Expect(kubeCli).NotTo(gomega.BeNil())
+
+	return &TestConfig{
+		Context:           context.Background(),
+		KubeCli:           kubeCli,
+		NsName:            nsName,
+		RestConfig:        cfg,
+		Scheme:            runtime.NewScheme(),
+		ExistsTimeout:     env.GetEnvDuration("EXISTS_TIMEOUT", defaultExistsTimeout, ginkgo.GinkgoLogr),
+		ReadyTimeout:      env.GetEnvDuration("READY_TIMEOUT", defaultReadyTimeout, ginkgo.GinkgoLogr),
+		ModelReadyTimeout: env.GetEnvDuration("MODEL_READY_TIMEOUT", defaultModelReadyTimeout, ginkgo.GinkgoLogr),
+		Interval:          defaultInterval,
+	}
+}
+
+// CreateCli creates the Kubernetes client used in the tests, invoked after the scheme has been setup.
+func (testConfig *TestConfig) CreateCli() {
+	var err error
+	testConfig.K8sClient, err = client.New(testConfig.RestConfig, client.Options{Scheme: testConfig.Scheme})
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+	gomega.Expect(testConfig.K8sClient).NotTo(gomega.BeNil())
+}
+
 // DeleteClusterResources deletes all cluster-scoped objects the tests typically create.
-func DeleteClusterResources(ctx context.Context, cli client.Client) error {
+func DeleteClusterResources(testConfig *TestConfig) error {
 	binding := &rbacv1.ClusterRoleBinding{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: "auth-reviewer-binding",
 		},
 	}
-	err := cli.Delete(ctx, binding, client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err := testConfig.K8sClient.Delete(testConfig.Context, binding, client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
@@ -57,7 +118,7 @@ func DeleteClusterResources(ctx context.Context, cli client.Client) error {
 			Name: "auth-reviewer",
 		},
 	}
-	err = cli.Delete(ctx, role, client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.Delete(testConfig.Context, role, client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
@@ -66,7 +127,7 @@ func DeleteClusterResources(ctx context.Context, cli client.Client) error {
 			Name: "inference-gateway-sa-metrics-reader-role-binding",
 		},
 	}
-	err = cli.Delete(ctx, metricsReaderBinding, client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.Delete(testConfig.Context, metricsReaderBinding, client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
@@ -75,7 +136,7 @@ func DeleteClusterResources(ctx context.Context, cli client.Client) error {
 			Name: "inference-gateway-metrics-reader",
 		},
 	}
-	err = cli.Delete(ctx, metricsReaderRole, client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.Delete(testConfig.Context, metricsReaderRole, client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
@@ -84,7 +145,7 @@ func DeleteClusterResources(ctx context.Context, cli client.Client) error {
 			Name: "inferenceobjectives.inference.networking.x-k8s.io",
 		},
 	}
-	err = cli.Delete(ctx, model, client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.Delete(testConfig.Context, model, client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
@@ -93,7 +154,7 @@ func DeleteClusterResources(ctx context.Context, cli client.Client) error {
 			Name: "inferencepools.inference.networking.x-k8s.io",
 		},
 	}
-	err = cli.Delete(ctx, pool, client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.Delete(testConfig.Context, pool, client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
@@ -102,49 +163,49 @@ func DeleteClusterResources(ctx context.Context, cli client.Client) error {
 
 // DeleteNamespacedResources deletes all namespace-scoped objects the tests typically create.
 // The given namespace will also be deleted if it's not "default".
-func DeleteNamespacedResources(ctx context.Context, cli client.Client, ns string) error {
-	if ns == "" {
+func DeleteNamespacedResources(testConfig *TestConfig) error {
+	if testConfig.NsName == "" {
 		return nil
 	}
-	err := cli.DeleteAllOf(ctx, &appsv1.Deployment{}, client.InNamespace(ns), client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err := testConfig.K8sClient.DeleteAllOf(testConfig.Context, &appsv1.Deployment{}, client.InNamespace(testConfig.NsName), client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
-	err = cli.DeleteAllOf(ctx, &corev1.Service{}, client.InNamespace(ns), client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.DeleteAllOf(testConfig.Context, &corev1.Service{}, client.InNamespace(testConfig.NsName), client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
-	err = cli.DeleteAllOf(ctx, &corev1.Pod{}, client.InNamespace(ns), client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.DeleteAllOf(testConfig.Context, &corev1.Pod{}, client.InNamespace(testConfig.NsName), client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
-	err = cli.DeleteAllOf(ctx, &corev1.ConfigMap{}, client.InNamespace(ns), client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.DeleteAllOf(testConfig.Context, &corev1.ConfigMap{}, client.InNamespace(testConfig.NsName), client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
-	err = cli.DeleteAllOf(ctx, &corev1.Secret{}, client.InNamespace(ns), client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.DeleteAllOf(testConfig.Context, &corev1.Secret{}, client.InNamespace(testConfig.NsName), client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
-	err = cli.DeleteAllOf(ctx, &corev1.ServiceAccount{}, client.InNamespace(ns), client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.DeleteAllOf(testConfig.Context, &corev1.ServiceAccount{}, client.InNamespace(testConfig.NsName), client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
-	err = cli.DeleteAllOf(ctx, &v1.InferencePool{}, client.InNamespace(ns), client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.DeleteAllOf(testConfig.Context, &v1.InferencePool{}, client.InNamespace(testConfig.NsName), client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
-	err = cli.DeleteAllOf(ctx, &v1alpha2.InferenceObjective{}, client.InNamespace(ns), client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err = testConfig.K8sClient.DeleteAllOf(testConfig.Context, &v1alpha2.InferenceObjective{}, client.InNamespace(testConfig.NsName), client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
-	if ns != "default" {
+	if testConfig.NsName != "default" {
 		ns := &corev1.Namespace{
 			ObjectMeta: metav1.ObjectMeta{
-				Name: ns,
+				Name: testConfig.NsName,
 			},
 		}
-		if err := cli.Delete(ctx, ns, client.PropagationPolicy(metav1.DeletePropagationForeground)); err != nil && !apierrors.IsNotFound(err) {
+		if err := testConfig.K8sClient.Delete(testConfig.Context, ns, client.PropagationPolicy(metav1.DeletePropagationForeground)); err != nil && !apierrors.IsNotFound(err) {
 			return err
 		}
 	}
@@ -152,11 +213,11 @@ func DeleteNamespacedResources(ctx context.Context, cli client.Client, ns string
 }
 
 // DeleteInferenceObjectiveResources deletes all InferenceObjective objects in the given namespace.
-func DeleteInferenceObjectiveResources(ctx context.Context, cli client.Client, ns string) error {
-	if ns == "" {
+func DeleteInferenceObjectiveResources(testConfig *TestConfig) error {
+	if testConfig.NsName == "" {
 		return nil
 	}
-	err := cli.DeleteAllOf(ctx, &v1alpha2.InferenceObjective{}, client.InNamespace(ns), client.PropagationPolicy(metav1.DeletePropagationForeground))
+	err := testConfig.K8sClient.DeleteAllOf(testConfig.Context, &v1alpha2.InferenceObjective{}, client.InNamespace(testConfig.NsName), client.PropagationPolicy(metav1.DeletePropagationForeground))
 	if err != nil && !apierrors.IsNotFound(err) {
 		return err
 	}
@@ -164,7 +225,7 @@ func DeleteInferenceObjectiveResources(ctx context.Context, cli client.Client, n
 }
 
 // PodReady checks if the given Pod reports the "Ready" status condition before the given timeout.
-func PodReady(ctx context.Context, cli client.Client, pod *corev1.Pod, timeout, interval time.Duration) {
+func PodReady(testConfig *TestConfig, pod *corev1.Pod) {
 	ginkgo.By(fmt.Sprintf("Checking pod %s/%s status is: %s", pod.Namespace, pod.Name, corev1.PodReady))
 	conditions := []corev1.PodCondition{
 		{
@@ -172,13 +233,14 @@ func PodReady(ctx context.Context, cli client.Client, pod *corev1.Pod, timeout,
 			Status: corev1.ConditionTrue,
 		},
 	}
-	gomega.Eventually(checkPodStatus, timeout, interval).WithArguments(ctx, cli, pod, conditions).Should(gomega.BeTrue())
+	gomega.Eventually(checkPodStatus, testConfig.ExistsTimeout, testConfig.Interval).
+		WithArguments(testConfig, pod, conditions).Should(gomega.BeTrue())
 }
 
 // checkPodStatus checks if the given Pod status matches the expected conditions.
-func checkPodStatus(ctx context.Context, cli client.Client, pod *corev1.Pod, conditions []corev1.PodCondition) (bool, error) {
+func checkPodStatus(testConfig *TestConfig, pod *corev1.Pod, conditions []corev1.PodCondition) (bool, error) {
 	var fetchedPod corev1.Pod
-	if err := cli.Get(ctx, types.NamespacedName{Namespace: pod.Namespace, Name: pod.Name}, &fetchedPod); err != nil {
+	if err := testConfig.K8sClient.Get(testConfig.Context, types.NamespacedName{Namespace: pod.Namespace, Name: pod.Name}, &fetchedPod); err != nil {
 		return false, err
 	}
 	found := 0
@@ -193,7 +255,7 @@ func checkPodStatus(ctx context.Context, cli client.Client, pod *corev1.Pod, con
 }
 
 // DeploymentAvailable checks if the given Deployment reports the "Available" status condition before the given timeout.
-func DeploymentAvailable(ctx context.Context, cli client.Client, deploy *appsv1.Deployment, timeout, interval time.Duration) {
+func DeploymentAvailable(testConfig *TestConfig, deploy *appsv1.Deployment) {
 	ginkgo.By(fmt.Sprintf("Checking if deployment %s/%s status is: %s", deploy.Namespace, deploy.Name, appsv1.DeploymentAvailable))
 	conditions := []appsv1.DeploymentCondition{
 		{
@@ -201,19 +263,21 @@ func DeploymentAvailable(ctx context.Context, cli client.Client, deploy *appsv1.
 			Status: corev1.ConditionTrue,
 		},
 	}
-	gomega.Eventually(checkDeploymentStatus, timeout, interval).WithArguments(ctx, cli, deploy, conditions).Should(gomega.BeTrue())
+	gomega.Eventually(checkDeploymentStatus, testConfig.ModelReadyTimeout, testConfig.Interval).
+		WithArguments(testConfig.Context, testConfig.K8sClient, deploy, conditions).
+		Should(gomega.BeTrue())
 }
 
 // DeploymentReadyReplicas checks if the given Deployment has at least `count` ready replicas before the given timeout.
-func DeploymentReadyReplicas(ctx context.Context, cli client.Client, deploy *appsv1.Deployment, count int, timeout, interval time.Duration) {
+func DeploymentReadyReplicas(testConfig *TestConfig, deploy *appsv1.Deployment, count int) {
 	ginkgo.By(fmt.Sprintf("Checking if deployment %s/%s has at least %d ready replica(s)", deploy.Namespace, deploy.Name, count))
 	gomega.Eventually(func(g gomega.Gomega) {
 		var fetchedDeploy appsv1.Deployment
-		err := cli.Get(ctx, types.NamespacedName{Namespace: deploy.Namespace, Name: deploy.Name}, &fetchedDeploy)
+		err := testConfig.K8sClient.Get(testConfig.Context, types.NamespacedName{Namespace: deploy.Namespace, Name: deploy.Name}, &fetchedDeploy)
 		g.Expect(err).NotTo(gomega.HaveOccurred())
 		g.Expect(fetchedDeploy.Status.ReadyReplicas).To(gomega.BeNumerically(">=", count),
 			fmt.Sprintf("Deployment only has %d ready replicas, want at least %d", fetchedDeploy.Status.ReadyReplicas, count))
-	}, timeout, interval).Should(gomega.Succeed())
+	}, testConfig.ModelReadyTimeout, testConfig.Interval).Should(gomega.Succeed())
 }
 
 // checkDeploymentStatus checks if the given Deployment status matches the expected conditions.
@@ -234,7 +298,7 @@ func checkDeploymentStatus(ctx context.Context, cli client.Client, deploy *appsv
 }
 
 // CRDEstablished checks if the given CRD reports the "Established" status condition before the given timeout.
-func CRDEstablished(ctx context.Context, cli client.Client, crd *apiextv1.CustomResourceDefinition, timeout, interval time.Duration) {
+func CRDEstablished(testConfig *TestConfig, crd *apiextv1.CustomResourceDefinition) {
 	ginkgo.By(fmt.Sprintf("Checking CRD %s status is: %s", crd.Name, apiextv1.Established))
 	conditions := []apiextv1.CustomResourceDefinitionCondition{
 		{
@@ -242,7 +306,9 @@ func CRDEstablished(ctx context.Context, cli client.Client, crd *apiextv1.Custom
 			Status: apiextv1.ConditionTrue,
 		},
 	}
-	gomega.Eventually(checkCrdStatus, timeout, interval).WithArguments(ctx, cli, crd, conditions).Should(gomega.BeTrue())
+	gomega.Eventually(checkCrdStatus, testConfig.ReadyTimeout, testConfig.Interval).
+		WithArguments(testConfig.Context, testConfig.K8sClient, crd, conditions).
+		Should(gomega.BeTrue())
 }
 
 // checkCrdStatus checks if the given CRD status matches the expected conditions.
@@ -268,22 +334,14 @@ func checkCrdStatus(
 }
 
 // ExecCommandInPod runs a command in a given container of a given Pod, returning combined stdout+stderr.
-func ExecCommandInPod(
-	ctx context.Context,
-	cfg *rest.Config,
-	scheme *runtime.Scheme,
-	kubeClient *kubernetes.Clientset,
-	podNamespace, podName, containerName string,
-	cmd []string,
-) (string, error) {
-
-	parameterCodec := runtime.NewParameterCodec(scheme)
+func ExecCommandInPod(testConfig *TestConfig, podName, containerName string, cmd []string) (string, error) {
+	parameterCodec := runtime.NewParameterCodec(testConfig.Scheme)
 
-	req := kubeClient.CoreV1().RESTClient().
+	req := testConfig.KubeCli.CoreV1().RESTClient().
 		Post().
 		Resource("pods").
 		Name(podName).
-		Namespace(podNamespace).
+		Namespace(testConfig.NsName).
 		SubResource("exec").
 		VersionedParams(&corev1.PodExecOptions{
 			Container: containerName,
@@ -294,13 +352,13 @@ func ExecCommandInPod(
 			TTY:       false,
 		}, parameterCodec)
 
-	exec, err := remotecommand.NewSPDYExecutor(cfg, "POST", req.URL())
+	exec, err := remotecommand.NewSPDYExecutor(testConfig.RestConfig, "POST", req.URL())
 	if err != nil {
 		return "", fmt.Errorf("could not initialize executor: %w", err)
 	}
 
 	var stdout, stderr bytes.Buffer
-	execErr := exec.StreamWithContext(ctx, remotecommand.StreamOptions{
+	execErr := exec.StreamWithContext(testConfig.Context, remotecommand.StreamOptions{
 		Stdout: &stdout,
 		Stderr: &stderr,
 	})
@@ -316,8 +374,135 @@ func ExecCommandInPod(
 
 // EventuallyExists checks if a Kubernetes resource exists and returns nil if successful.
 // It takes a function `getResource` which retrieves the resource and returns an error if it doesn't exist.
-func EventuallyExists(ctx context.Context, getResource func() error, timeout, interval time.Duration) {
+func EventuallyExists(testConfig *TestConfig, getResource func() error) {
 	gomega.Eventually(func() error {
 		return getResource()
-	}, timeout, interval).Should(gomega.Succeed())
+	}, testConfig.ExistsTimeout, testConfig.Interval).Should(gomega.Succeed())
+}
+
+// CreateObjsFromYaml creates K8S objects from yaml and waits for them to be instantiated
+func CreateObjsFromYaml(testConfig *TestConfig, docs []string) []string {
+	objNames := []string{}
+
+	// For each doc, decode and create
+	decoder := serializer.NewCodecFactory(testConfig.Scheme).UniversalDeserializer()
+	for _, doc := range docs {
+		trimmed := strings.TrimSpace(doc)
+		if trimmed == "" {
+			continue
+		}
+		// Decode into a runtime.Object
+		obj, gvk, decodeErr := decoder.Decode([]byte(trimmed), nil, nil)
+		gomega.Expect(decodeErr).NotTo(gomega.HaveOccurred(),
+			"Failed to decode YAML document to a Kubernetes object")
+
+		ginkgo.By(fmt.Sprintf("Decoded GVK: %s", gvk))
+
+		unstrObj, ok := obj.(*unstructured.Unstructured)
+		if !ok {
+			// Fallback if it's a typed object
+			unstrObj = &unstructured.Unstructured{}
+			// Convert typed to unstructured
+			err := testConfig.Scheme.Convert(obj, unstrObj, nil)
+			gomega.Expect(err).NotTo(gomega.HaveOccurred())
+		}
+
+		unstrObj.SetNamespace(testConfig.NsName)
+		kind := unstrObj.GetKind()
+		name := unstrObj.GetName()
+		objNames = append(objNames, kind+"/"+name)
+
+		// Create the object
+		err := testConfig.K8sClient.Create(testConfig.Context, unstrObj, &client.CreateOptions{})
+		gomega.Expect(err).NotTo(gomega.HaveOccurred(),
+			"Failed to create object from YAML")
+
+		// Wait for the created object to exist.
+		clientObj := getClientObject(kind)
+		EventuallyExists(testConfig, func() error {
+			return testConfig.K8sClient.Get(testConfig.Context,
+				types.NamespacedName{Namespace: testConfig.NsName, Name: name}, clientObj)
+		})
+
+		switch kind {
+		case "CustomResourceDefinition":
+			// Wait for the CRD to be established.
+			CRDEstablished(testConfig, clientObj.(*apiextv1.CustomResourceDefinition))
+		case "Deployment":
+			// Wait for the deployment to be available.
+			DeploymentAvailable(testConfig, clientObj.(*appsv1.Deployment))
+		case "Pod":
+			// Wait for the pod to be ready.
+			PodReady(testConfig, clientObj.(*corev1.Pod))
+		}
+	}
+	return objNames
+}
+
+// DeleteObjects deletes  set of Kubernetes objects in the form of kind/name
+func DeleteObjects(testConfig *TestConfig, kindAndNames []string) {
+	for _, kindAndName := range kindAndNames {
+		split := strings.Split(kindAndName, "/")
+		clientObj := getClientObject(split[0])
+		err := testConfig.K8sClient.Get(testConfig.Context,
+			types.NamespacedName{Namespace: testConfig.NsName, Name: split[1]}, clientObj)
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
+		err = testConfig.K8sClient.Delete(testConfig.Context, clientObj)
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
+		gomega.Eventually(func() bool {
+			clientObj := getClientObject(split[0])
+			err := testConfig.K8sClient.Get(testConfig.Context,
+				types.NamespacedName{Namespace: testConfig.NsName, Name: split[1]}, clientObj)
+			return apierrors.IsNotFound(err)
+		}, testConfig.ExistsTimeout, testConfig.Interval).Should(gomega.BeTrue())
+	}
+}
+
+// applyYAMLFile reads a file containing YAML (possibly multiple docs)
+// and applies each object to the cluster.
+func ApplyYAMLFile(testConfig *TestConfig, filePath string) {
+	// Create the resources from the manifest file
+	CreateObjsFromYaml(testConfig, ReadYaml(filePath))
+}
+
+// ReadYaml is a helper function to read in K8S YAML files and split by the --- separator
+func ReadYaml(filePath string) []string {
+	ginkgo.By("Reading YAML file: " + filePath)
+	yamlBytes, err := os.ReadFile(filePath)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	// Split multiple docs, if needed
+	return strings.Split(string(yamlBytes), "\n---")
+}
+
+func getClientObject(kind string) client.Object {
+	switch strings.ToLower(kind) {
+	case "clusterrole":
+		return &rbacv1.ClusterRole{}
+	case "clusterrolebinding":
+		return &rbacv1.ClusterRoleBinding{}
+	case "configmap":
+		return &corev1.ConfigMap{}
+	case "customresourcedefinition":
+		return &apiextv1.CustomResourceDefinition{}
+	case "deployment":
+		return &appsv1.Deployment{}
+	case "inferencepool":
+		return &v1.InferencePool{}
+	case "pod":
+		return &corev1.Pod{}
+	case "role":
+		return &rbacv1.Role{}
+	case "rolebinding":
+		return &rbacv1.RoleBinding{}
+	case "secret":
+		return &corev1.Secret{}
+	case "service":
+		return &corev1.Service{}
+	case "serviceaccount":
+		return &corev1.ServiceAccount{}
+	default:
+		ginkgo.Fail("unsupported K8S kind "+kind, 1)
+		return nil
+	}
 }