From 3ef30f99bea3717744477d64a75a9b0f5bf73a06 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Tue, 23 Mar 2021 14:31:59 -0400 Subject: [PATCH] pull in stereoscope cache fix + add test cache makefile target helpers Signed-off-by: Alex Goodman --- Makefile | 31 ++- go.mod | 2 +- go.sum | 4 +- .../snapshot/TestJSONImgsPresenter.golden | 16 +- .../stereoscope-fixture-image-simple.golden | Bin 16896 -> 16896 bytes ...scope-fixture-packages-image-simple.golden | Bin 0 -> 16896 bytes syft/presenter/json/package.go | 181 ------------------ 7 files changed, 36 insertions(+), 198 deletions(-) create mode 100644 internal/presenter/packages/test-fixtures/snapshot/stereoscope-fixture-packages-image-simple.golden delete mode 100644 syft/presenter/json/package.go diff --git a/Makefile b/Makefile index 6f4632476..fa3c5879e 100644 --- a/Makefile +++ b/Makefile @@ -147,7 +147,7 @@ validate-cyclonedx-schema: .PHONY: unit unit: $(RESULTSDIR) fixtures ## Run unit tests (with coverage) $(call title,Running unit tests) - go test -coverprofile $(COVER_REPORT) $(shell go list ./... | grep -v anchore/syft/test) + go test -coverprofile $(COVER_REPORT) $(shell go list ./... | grep -v anchore/syft/test) @go tool cover -func $(COVER_REPORT) | grep total | awk '{print substr($$3, 1, length($$3)-1)}' > $(COVER_TOTAL) @echo "Coverage: $$(cat $(COVER_TOTAL))" @if [ $$(echo "$$(cat $(COVER_TOTAL)) >= $(COVERAGE_THRESHOLD)" | bc -l) -ne 1 ]; then echo "$(RED)$(BOLD)Failed coverage quality gate (> $(COVERAGE_THRESHOLD)%)$(RESET)" && false; fi @@ -189,10 +189,6 @@ fixtures: generate-json-schema: ## Generate a new json schema cd schema/json && go run generate.go -.PHONY: clear-test-cache -clear-test-cache: ## Delete all test cache (built docker image tars) - find . -type f -wholename "**/test-fixtures/cache/*.tar" -delete - .PHONY: build build: $(SNAPSHOTDIR) ## Build release snapshot binaries and packages @@ -313,7 +309,7 @@ release: clean-dist changelog-release ## Build and publish final binaries and pa .PHONY: clean -clean: clean-dist clean-snapshot ## Remove previous builds and result reports +clean: clean-dist clean-snapshot clean-test-image-cache ## Remove previous builds, result reports, and test cache rm -rf $(RESULTSDIR)/* .PHONY: clean-snapshot @@ -323,3 +319,26 @@ clean-snapshot: .PHONY: clean-dist clean-dist: rm -rf $(DISTDIR) $(TEMPDIR)/goreleaser.yaml + +clean-test-image-cache: clean-test-image-tar-cache clean-test-image-docker-cache + +.PHONY: clear-test-image-tar-cache +clean-test-image-tar-cache: ## Delete all test cache (built docker image tars) + find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" -delete + +.PHONY: clear-test-image-docker-cache +clean-test-image-docker-cache: ## Purge all test docker images + docker images --format '{{.ID}} {{.Repository}}' | grep stereoscope-fixture- | awk '{print $$1}' | uniq | xargs docker rmi --force + +.PHONY: show-test-image-cache +show-test-image-cache: ## Show all docker and image tar cache + $(call title,Docker daemon cache) + @docker images --format '{{.ID}} {{.Repository}}:{{.Tag}}' | grep stereoscope-fixture- | sort + + $(call title,Tar cache) + @find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" | sort + +.PHONY: show-test-snapshots +show-test-snapshots: ## Show all test snapshots + $(call title,Test snapshots) + @find . -type f -wholename "**/test-fixtures/snapshot/*" | sort \ No newline at end of file diff --git a/go.mod b/go.mod index 95354b280..5a9ded037 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/anchore/go-rpmdb v0.0.0-20201106153645-0043963c2e12 github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b - github.com/anchore/stereoscope v0.0.0-20210323145922-1f45cd8849b4 + github.com/anchore/stereoscope v0.0.0-20210323182342-47b72675ff65 github.com/antihax/optional v1.0.0 github.com/bmatcuk/doublestar/v2 v2.0.4 github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible diff --git a/go.sum b/go.sum index eecc235eb..3ec96d0c7 100644 --- a/go.sum +++ b/go.sum @@ -115,8 +115,8 @@ github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0v github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ= github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZVsCYMrIZBpFxwV26CbsuoEh5muXD5I1Ods= github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E= -github.com/anchore/stereoscope v0.0.0-20210323145922-1f45cd8849b4 h1:Uuvne+/Mgeyu3fR1JCxiFUQQo2Gp5vXTInum3GbhbwM= -github.com/anchore/stereoscope v0.0.0-20210323145922-1f45cd8849b4/go.mod h1:G7tFR0iI9r6AvibmXKA9v010pRS1IIJgd0t6fOMDxCw= +github.com/anchore/stereoscope v0.0.0-20210323182342-47b72675ff65 h1:r3tiir6UCgj/YeTqy4s2bfhZ9SuJYNlXx1Z9e/eLrbI= +github.com/anchore/stereoscope v0.0.0-20210323182342-47b72675ff65/go.mod h1:G7tFR0iI9r6AvibmXKA9v010pRS1IIJgd0t6fOMDxCw= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= diff --git a/internal/presenter/packages/test-fixtures/snapshot/TestJSONImgsPresenter.golden b/internal/presenter/packages/test-fixtures/snapshot/TestJSONImgsPresenter.golden index dbb11f32c..0c27b16d9 100644 --- a/internal/presenter/packages/test-fixtures/snapshot/TestJSONImgsPresenter.golden +++ b/internal/presenter/packages/test-fixtures/snapshot/TestJSONImgsPresenter.golden @@ -9,7 +9,7 @@ "locations": [ { "path": "/somefile-1.txt", - "layerID": "sha256:e158b57d6f5a96ef5fd22f2fe76c70b5ba6ff5b2619f9d83125b2aad0492ac7b" + "layerID": "sha256:3de16c5b8659a2e8d888b8ded8427be7a5686a3c8c4e4dd30de20f362827285b" } ], "licenses": [ @@ -40,7 +40,7 @@ "locations": [ { "path": "/somefile-2.txt", - "layerID": "sha256:da21056e7bf4308ecea0c0836848a7fe92f38fdcf35bc09ee6d98e7ab7beeebf" + "layerID": "sha256:366a3f5653e34673b875891b021647440d0127c2ef041e3b1a22da2a7d4f3703" } ], "licenses": [], @@ -67,27 +67,27 @@ "type": "image", "target": { "userInput": "user-image-input", - "imageID": "sha256:92fbdd71302c666029f11ef5ea49caba6e97daa86cb4dce7874377b26c731d65", + "imageID": "sha256:c2b46b4eb06296933b7cf0722683964e9ecbd93265b9ef6ae9642e3952afbba0", "manifestDigest": "sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368", "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "tags": [ - "stereoscope-fixture-image-simple:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + "stereoscope-fixture-image-simple:85066c51088bdd274f7a89e99e00490f666c49e72ffc955707cd6e18f0e22c5b" ], "imageSize": 38, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "digest": "sha256:e158b57d6f5a96ef5fd22f2fe76c70b5ba6ff5b2619f9d83125b2aad0492ac7b", + "digest": "sha256:3de16c5b8659a2e8d888b8ded8427be7a5686a3c8c4e4dd30de20f362827285b", "size": 22 }, { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "digest": "sha256:da21056e7bf4308ecea0c0836848a7fe92f38fdcf35bc09ee6d98e7ab7beeebf", + "digest": "sha256:366a3f5653e34673b875891b021647440d0127c2ef041e3b1a22da2a7d4f3703", "size": 16 } ], - "manifest": "eyJzY2hlbWFWZXJzaW9uIjoyLCJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuZG9ja2VyLmRpc3RyaWJ1dGlvbi5tYW5pZmVzdC52Mitqc29uIiwiY29uZmlnIjp7Im1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuY29udGFpbmVyLmltYWdlLnYxK2pzb24iLCJzaXplIjoxNTg2LCJkaWdlc3QiOiJzaGEyNTY6OTJmYmRkNzEzMDJjNjY2MDI5ZjExZWY1ZWE0OWNhYmE2ZTk3ZGFhODZjYjRkY2U3ODc0Mzc3YjI2YzczMWQ2NSJ9LCJsYXllcnMiOlt7Im1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuaW1hZ2Uucm9vdGZzLmRpZmYudGFyLmd6aXAiLCJzaXplIjoyMDQ4LCJkaWdlc3QiOiJzaGEyNTY6ZTE1OGI1N2Q2ZjVhOTZlZjVmZDIyZjJmZTc2YzcwYjViYTZmZjViMjYxOWY5ZDgzMTI1YjJhYWQwNDkyYWM3YiJ9LHsibWVkaWFUeXBlIjoiYXBwbGljYXRpb24vdm5kLmRvY2tlci5pbWFnZS5yb290ZnMuZGlmZi50YXIuZ3ppcCIsInNpemUiOjIwNDgsImRpZ2VzdCI6InNoYTI1NjpkYTIxMDU2ZTdiZjQzMDhlY2VhMGMwODM2ODQ4YTdmZTkyZjM4ZmRjZjM1YmMwOWVlNmQ5OGU3YWI3YmVlZWJmIn1dfQ==", - "config": "eyJhcmNoaXRlY3R1cmUiOiJhbWQ2NCIsImNvbmZpZyI6eyJIb3N0bmFtZSI6IiIsIkRvbWFpbm5hbWUiOiIiLCJVc2VyIjoiIiwiQXR0YWNoU3RkaW4iOmZhbHNlLCJBdHRhY2hTdGRvdXQiOmZhbHNlLCJBdHRhY2hTdGRlcnIiOmZhbHNlLCJUdHkiOmZhbHNlLCJPcGVuU3RkaW4iOmZhbHNlLCJTdGRpbk9uY2UiOmZhbHNlLCJFbnYiOlsiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iXSwiQ21kIjpudWxsLCJJbWFnZSI6InNoYTI1Njo3MDRjZGI0ZDViYmNlMDhjNzI1N2I0OTUxMWM5YzBlYTc2N2UwNzdmZDhiOGIzNDUxOGMzNjg3YTdmZjFlNTlkIiwiVm9sdW1lcyI6bnVsbCwiV29ya2luZ0RpciI6IiIsIkVudHJ5cG9pbnQiOm51bGwsIk9uQnVpbGQiOm51bGwsIkxhYmVscyI6bnVsbH0sImNvbnRhaW5lcl9jb25maWciOnsiSG9zdG5hbWUiOiIiLCJEb21haW5uYW1lIjoiIiwiVXNlciI6IiIsIkF0dGFjaFN0ZGluIjpmYWxzZSwiQXR0YWNoU3Rkb3V0IjpmYWxzZSwiQXR0YWNoU3RkZXJyIjpmYWxzZSwiVHR5IjpmYWxzZSwiT3BlblN0ZGluIjpmYWxzZSwiU3RkaW5PbmNlIjpmYWxzZSwiRW52IjpbIlBBVEg9L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluIl0sIkNtZCI6WyIvYmluL3NoIiwiLWMiLCIjKG5vcCkgQUREIGZpbGU6ZGYzYjc0NGY1NGE5YjE2YjliOWFlZDQwZTNlOThkOWNhMmI0OWY1YTc3ZDlmYThhOTc2OTBkN2JhZjU4ODgyMCBpbiAvc29tZWZpbGUtMi50eHQgIl0sIkltYWdlIjoic2hhMjU2OjcwNGNkYjRkNWJiY2UwOGM3MjU3YjQ5NTExYzljMGVhNzY3ZTA3N2ZkOGI4YjM0NTE4YzM2ODdhN2ZmMWU1OWQiLCJWb2x1bWVzIjpudWxsLCJXb3JraW5nRGlyIjoiIiwiRW50cnlwb2ludCI6bnVsbCwiT25CdWlsZCI6bnVsbCwiTGFiZWxzIjpudWxsfSwiY3JlYXRlZCI6IjIwMjEtMDMtMTNUMTY6MTU6NTAuMDM2MDAwNloiLCJkb2NrZXJfdmVyc2lvbiI6IjIwLjEwLjIiLCJoaXN0b3J5IjpbeyJjcmVhdGVkIjoiMjAyMS0wMy0xM1QxNjoxNTo0OS44NjA5MDgyWiIsImNyZWF0ZWRfYnkiOiIvYmluL3NoIC1jICMobm9wKSBBREQgZmlsZTphYzMyZGEyM2Q1MWU4MDFmMDJmOTI0MTIzZWQzMDk5MGViM2YwZmVjMWI5ZWQ0ZjBiMDZjMjRlODhiOWMzNjk1IGluIC9zb21lZmlsZS0xLnR4dCAifSx7ImNyZWF0ZWQiOiIyMDIxLTAzLTEzVDE2OjE1OjUwLjAzNjAwMDZaIiwiY3JlYXRlZF9ieSI6Ii9iaW4vc2ggLWMgIyhub3ApIEFERCBmaWxlOmRmM2I3NDRmNTRhOWIxNmI5YjlhZWQ0MGUzZTk4ZDljYTJiNDlmNWE3N2Q5ZmE4YTk3NjkwZDdiYWY1ODg4MjAgaW4gL3NvbWVmaWxlLTIudHh0ICJ9XSwib3MiOiJsaW51eCIsInJvb3RmcyI6eyJ0eXBlIjoibGF5ZXJzIiwiZGlmZl9pZHMiOlsic2hhMjU2OmUxNThiNTdkNmY1YTk2ZWY1ZmQyMmYyZmU3NmM3MGI1YmE2ZmY1YjI2MTlmOWQ4MzEyNWIyYWFkMDQ5MmFjN2IiLCJzaGEyNTY6ZGEyMTA1NmU3YmY0MzA4ZWNlYTBjMDgzNjg0OGE3ZmU5MmYzOGZkY2YzNWJjMDllZTZkOThlN2FiN2JlZWViZiJdfX0=", + "manifest": "eyJzY2hlbWFWZXJzaW9uIjoyLCJtZWRpYVR5cGUiOiJhcHBsaWNhdGlvbi92bmQuZG9ja2VyLmRpc3RyaWJ1dGlvbi5tYW5pZmVzdC52Mitqc29uIiwiY29uZmlnIjp7Im1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuY29udGFpbmVyLmltYWdlLnYxK2pzb24iLCJzaXplIjoxNTg2LCJkaWdlc3QiOiJzaGEyNTY6YzJiNDZiNGViMDYyOTY5MzNiN2NmMDcyMjY4Mzk2NGU5ZWNiZDkzMjY1YjllZjZhZTk2NDJlMzk1MmFmYmJhMCJ9LCJsYXllcnMiOlt7Im1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuaW1hZ2Uucm9vdGZzLmRpZmYudGFyLmd6aXAiLCJzaXplIjoyMDQ4LCJkaWdlc3QiOiJzaGEyNTY6M2RlMTZjNWI4NjU5YTJlOGQ4ODhiOGRlZDg0MjdiZTdhNTY4NmEzYzhjNGU0ZGQzMGRlMjBmMzYyODI3Mjg1YiJ9LHsibWVkaWFUeXBlIjoiYXBwbGljYXRpb24vdm5kLmRvY2tlci5pbWFnZS5yb290ZnMuZGlmZi50YXIuZ3ppcCIsInNpemUiOjIwNDgsImRpZ2VzdCI6InNoYTI1NjozNjZhM2Y1NjUzZTM0NjczYjg3NTg5MWIwMjE2NDc0NDBkMDEyN2MyZWYwNDFlM2IxYTIyZGEyYTdkNGYzNzAzIn1dfQ==", + "config": "eyJhcmNoaXRlY3R1cmUiOiJhbWQ2NCIsImNvbmZpZyI6eyJIb3N0bmFtZSI6IiIsIkRvbWFpbm5hbWUiOiIiLCJVc2VyIjoiIiwiQXR0YWNoU3RkaW4iOmZhbHNlLCJBdHRhY2hTdGRvdXQiOmZhbHNlLCJBdHRhY2hTdGRlcnIiOmZhbHNlLCJUdHkiOmZhbHNlLCJPcGVuU3RkaW4iOmZhbHNlLCJTdGRpbk9uY2UiOmZhbHNlLCJFbnYiOlsiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iXSwiQ21kIjpudWxsLCJJbWFnZSI6InNoYTI1NjpkYWMyMTUwMzhjMDUwZTM1NzMwNTVlZmU4YTkwM2NkMWY5YmJkZmU0ZjlhZTlkODk5OTFjNTljY2M2OTA1MmU1IiwiVm9sdW1lcyI6bnVsbCwiV29ya2luZ0RpciI6IiIsIkVudHJ5cG9pbnQiOm51bGwsIk9uQnVpbGQiOm51bGwsIkxhYmVscyI6bnVsbH0sImNvbnRhaW5lcl9jb25maWciOnsiSG9zdG5hbWUiOiIiLCJEb21haW5uYW1lIjoiIiwiVXNlciI6IiIsIkF0dGFjaFN0ZGluIjpmYWxzZSwiQXR0YWNoU3Rkb3V0IjpmYWxzZSwiQXR0YWNoU3RkZXJyIjpmYWxzZSwiVHR5IjpmYWxzZSwiT3BlblN0ZGluIjpmYWxzZSwiU3RkaW5PbmNlIjpmYWxzZSwiRW52IjpbIlBBVEg9L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluIl0sIkNtZCI6WyIvYmluL3NoIiwiLWMiLCIjKG5vcCkgQUREIGZpbGU6ZGYzYjc0NGY1NGE5YjE2YjliOWFlZDQwZTNlOThkOWNhMmI0OWY1YTc3ZDlmYThhOTc2OTBkN2JhZjU4ODgyMCBpbiAvc29tZWZpbGUtMi50eHQgIl0sIkltYWdlIjoic2hhMjU2OmRhYzIxNTAzOGMwNTBlMzU3MzA1NWVmZThhOTAzY2QxZjliYmRmZTRmOWFlOWQ4OTk5MWM1OWNjYzY5MDUyZTUiLCJWb2x1bWVzIjpudWxsLCJXb3JraW5nRGlyIjoiIiwiRW50cnlwb2ludCI6bnVsbCwiT25CdWlsZCI6bnVsbCwiTGFiZWxzIjpudWxsfSwiY3JlYXRlZCI6IjIwMjEtMDMtMjNUMTg6MTU6NTguODcyMjg5OFoiLCJkb2NrZXJfdmVyc2lvbiI6IjIwLjEwLjIiLCJoaXN0b3J5IjpbeyJjcmVhdGVkIjoiMjAyMS0wMy0yM1QxODoxNTo1OC42MTc3OTU2WiIsImNyZWF0ZWRfYnkiOiIvYmluL3NoIC1jICMobm9wKSBBREQgZmlsZTphYzMyZGEyM2Q1MWU4MDFmMDJmOTI0MTIzZWQzMDk5MGViM2YwZmVjMWI5ZWQ0ZjBiMDZjMjRlODhiOWMzNjk1IGluIC9zb21lZmlsZS0xLnR4dCAifSx7ImNyZWF0ZWQiOiIyMDIxLTAzLTIzVDE4OjE1OjU4Ljg3MjI4OThaIiwiY3JlYXRlZF9ieSI6Ii9iaW4vc2ggLWMgIyhub3ApIEFERCBmaWxlOmRmM2I3NDRmNTRhOWIxNmI5YjlhZWQ0MGUzZTk4ZDljYTJiNDlmNWE3N2Q5ZmE4YTk3NjkwZDdiYWY1ODg4MjAgaW4gL3NvbWVmaWxlLTIudHh0ICJ9XSwib3MiOiJsaW51eCIsInJvb3RmcyI6eyJ0eXBlIjoibGF5ZXJzIiwiZGlmZl9pZHMiOlsic2hhMjU2OjNkZTE2YzViODY1OWEyZThkODg4YjhkZWQ4NDI3YmU3YTU2ODZhM2M4YzRlNGRkMzBkZTIwZjM2MjgyNzI4NWIiLCJzaGEyNTY6MzY2YTNmNTY1M2UzNDY3M2I4NzU4OTFiMDIxNjQ3NDQwZDAxMjdjMmVmMDQxZTNiMWEyMmRhMmE3ZDRmMzcwMyJdfX0=", "scope": "Squashed" } }, diff --git a/internal/presenter/packages/test-fixtures/snapshot/stereoscope-fixture-image-simple.golden b/internal/presenter/packages/test-fixtures/snapshot/stereoscope-fixture-image-simple.golden index 24d879f4948af2cdd6b512a7048d61847316ec24..10739912e2dde8dde068e7331a59d19f8a62b18d 100644 GIT binary patch literal 16896 zcmeI3S#R4$5Pw?mmcPo4_x8TXFLC_wALg$*i5FT9bON2_EK#yUa-Na-Xu z0N@$nT8{_oKbVbZDF@{8v-;oO9Z*4-5}Z)3280o!#9%1bi|(FcUN^47Ds`2#`fy$4 z?I^$OYX4VHU%dSF;J1%em(bRpV%6?fVbmO7u|K7Z4Tha<^07)?#eL)Ur~5n6@|Cvx z{|Bal&i()Ix-8Z_)4Kkz7+vZAI9=fQzmt~vjrafaERWeF>)H&my)0DV8fb-4tI3E^ z{2mfAS$zL$6O={c@&c+ic$MEf1UKP7YN#$_9yN^%Coh|r z7uh7aX$^bX^}TZ5e0UQo%(_f@*qmKoADlvQSI#1IPz0>RGX2xyT{bD^)9GIJc!p1O zdHL(i9WN{Ts+`VeP+!ITSypfJ;`m9vtnJgHsm@Nzyuf;0<~=BWndj4MQO})+=`#Dp zURL5|HqDFq`|M&(U)pqZSHq8|?hLB^b`5p!XHEYXAFltX(z@^e_bPOQ5p_9(luuzq z_nY_41_j>|wZ{GgSN@mdKV?dDJs^~}+l7Aozoo-%T{b6qJ!~7m@Wj=_c8G?eskc>H zFSpk~uYq0zy#^kN2Aq<{5FUe}F7POnR3=8HZFE*4w(~kL6Szr4X$68tt-&UmbYzKZ z1_Wk@jpa@{rYeF<{$L@ZwE?#z(sWK|K0f?W0HNq|8N`F_x~NV zn&xE(r}I!@L-dulW#b`OvT} z{fdLuCyq%qi7qfI2{(aAl#S=bL`q120tpY1ChL7nAQF~tqp{Y~AZ-W%OOp&F)_lV_ zHJ0HmQs#G1)p?1$IAdg=l6}@TtgnGQZ?cu#Mb{73WUdM)c>|%DS1n?9v#11`>pukJ zI~aQ(LJ?gD{%!GpMf&-F7wzNj_`aPI*Yp3S|Icmy-`jsX##oWMIQwDO;Q#xT=swtM zpw~dJfnEduQw;>%1S&7U6UD5u9Jh=i5!_%a!|?zBECe4dXG(etN#Pbw2?pFs=92f0 z?04rs9E)DzKa`-mXwQFk(B{swd$wNvPWfTNjn+luEApb-B+KZD*L@CzH@=r^cGO@pd{;bjI10m67KvxeEIP)cq+ke5geA)a zWgH?W))K(CP)LG6ah8c95uA7H*U^BCnXI^d^rOca$x09gjfUw{eV;)-f;<@vJuyq7h7c z&<@Y+mE*w#0V1M8BQTPs$u_bVz`^DPoR){~_;Ltqpn|dv`1 m*YwbKku=8IoKy2=d=|vYpg% z(YUQ_BV8#3u_#eT@;Oq+d+x+})LL=x5f8{nL!z=&aj6kQl2XqpHVVfe0$2D~rY-BA5KcDNKW8Yd|1GfY7W4 zi!tV7j)sT|uo>c?wqjW{CNDzu7S3XRo{g`vr)Av~W*XpWsBv6Qp~A=VUv;RKcOEs3 zaTl)|pBLFUnn@jwvfFFr9EP%aF;wvA>f&j0d3$~`3&mYIi_%HqpcAY5Pm1^1_$>SL z(dpCQNAtQGO-g4bquS=hc&&U}{CHz=X<3BR?9Ea3cnZ**Wg{q#>I)d;z`?&?el5z` zZ~aHd$NiX3!q`V@C1a5@qb(Lz1Gd346ll=OYiEdMI&veW*U>1WrO?PrYa&-l5!BC% z{-`dep_Miu!{$TNZ(DyhHRmn3^@Sl^jKNepZ<*)Tx`33Egi8?2F?QOaV5E=%Ng2Je zu(f0yD@TQrM#hK(*B*NQx}40Xq0Yv|d@?!8{w}L`d2xQ6uN3v9XsXLunYXiRS>vSm zW1dd{gk|x$v0<`${Q4;KrF#c6;(e&Wt@jdBM4SLZpXi8jh&&hu9-=iOXz7hn!hwtDf>e@GDJ>BW?6nts*q#5O zNNn;ym?Zx9Ftg+;`;6ki}f#eC^K)YwH{H)RE+=GoPK{43K# zB@pnpWWm2KiQ2aop1a{A`vceCR25s|0~!-NJ;k=7_!8c_@mTMZOt zL>380SWwDpU<)piS4ftfQBv@f&Iaui!IoM>ZqxK5?Xeb!t z5!1vtX+i3Ws|6Kc#6^%cGKy4i!61he@Uct*Asb*fKvncEQf?j6AqcNkkj6?ILa;G= zbDem&!x-iRwbC_MvzPo22>L*}K+69(z#QnT|GngYwC+gae-EJkUdsPC1j-M$jn3=8 zyZ;aFKiB_HFi`bGr5|5L)Da;l%%ZE8Ji8 z90YqFuQKPeo#X<5cl0vM%2RW`3}G~(3T5reSs29pLz~|_$lC<+L7h)$kfk1|MUF9| zRdm>4rcH$4gi~6JXdy;KqzMcMCK%+eQ|2HqfoqMeR2;rY=I zmJ>>{Q&SLZlDnK;esgeUG=sg35=CNJbVM`lB}bkGZW)P&N#?w^0%KyW4oZ3IwICcb zDPfifGW7o~^Q?3G2VsN+V;!{ktpBG-kPc>u2nJuwJBVP!QKyS;C%c`|X<3;9w$zl` z`olG)x2O9r6H~aevHM!U z6pN83Rb|}So64tIGK^+ahJ$2vEuU6jUJM1?x}14jU966eCL#Nr&iw2sbFhi!{Abz6 zWO$PN`Q-Td?}KSs3`V&#qd{rYYRU7^pRT0SmexTi-pxzo8TD=G-&0uGhpU)TQCMG;IDKx7gE#NySy;fP4ogkeI1r$}oQER86FF2QTYvxqDbjxc!RSna6L{BzFW z1!raln|6Bb$?v+;oygD(geV6cPDW`qJqNIhJg*{LxJ;^xNo{XN<^p(9b104Red=NC z4A>z#&`z|29mwHHQ0*BcE+; zrKNKZ2sGCJ=J7v-|9DORkrZJ6_ad2(-2PuCX&p8+6$5ZFKgA4KOVmRUhTvm_hVyS7 zdqBMUBSo%@VEiko0eF-x$Mn}igMGW#O&LF!2QK|Ohj!yHlGgSgZdx0=mV4 zRkmXuQ*V**HBuY+k0A5Au>Y7qOe#B&S*yc^*8X3^a94*FqWTY|wca#4kxb^?{!TwI0|Jw`94|b8p`rkbNM+k50f9^{_mifP? zVgNa@i76m-+;%Q;Lp{R}mQ&njy;55Zb5n`bEk!Pmu4d{7scO5S2=N{h3Q8`)|(jj0lKWpURpO>^~!WSf#w~>k${?WjG(!} zdm>qsM(Ln+fckNbqJUARgCsFJ&ACLUE>e%S9Ijv`%cVt_dD!dqEO3 zP`vx;+c>n_*#+>bOrh~74Lhs)*rfkNh^yX!EBzN>659B0x2&I2zf8)zYG~c9)L2P} ajg={x%^s8n?SV<{5-kEP0xbeNK;S