From 00e9dc287a5b0953a6ff09b1040cf79c5d8d00fa Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 18 May 2026 12:12:06 +0200 Subject: [PATCH 1/9] chore: bump schema versions for upcoming changes Signed-off-by: Jan Kowalleck --- schema/bom-1.6.proto | 2 +- schema/bom-1.6.xsd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/schema/bom-1.6.proto b/schema/bom-1.6.proto index b2d318ad4..b6194c7e7 100644 --- a/schema/bom-1.6.proto +++ b/schema/bom-1.6.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -package cyclonedx.v1_6; // version 1.6.1 +package cyclonedx.v1_6; // version 1.6.2 import "google/protobuf/timestamp.proto"; // Specifies attributes of the text diff --git a/schema/bom-1.6.xsd b/schema/bom-1.6.xsd index cee94c8ac..eae30ee47 100644 --- a/schema/bom-1.6.xsd +++ b/schema/bom-1.6.xsd @@ -22,7 +22,7 @@ limitations under the License. targetNamespace="http://cyclonedx.org/schema/bom/1.6" vc:minVersion="1.0" vc:maxVersion="1.1" - version="1.6.1"> + version="1.6.2"> From acedfbfb0ce263f2604795cefd53216f6dc5cb7d Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 19 May 2026 11:44:01 +0200 Subject: [PATCH 2/9] fix: back-port schema Signed-off-by: Jan Kowalleck --- schema/bom-1.5.proto | 6 ++++-- schema/bom-1.5.schema.json | 4 ++-- schema/bom-1.5.xsd | 26 +++++++++++++++-------- schema/bom-1.6.proto | 8 +++++--- schema/bom-1.6.schema.json | 14 ++++++------- schema/bom-1.6.xsd | 34 +++++++++++++++++++----------- schema/xmlcatalog.xml | 42 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 100 insertions(+), 34 deletions(-) create mode 100644 schema/xmlcatalog.xml diff --git a/schema/bom-1.5.proto b/schema/bom-1.5.proto index bea8f9ebe..a6ecd79d1 100644 --- a/schema/bom-1.5.proto +++ b/schema/bom-1.5.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -package cyclonedx.v1_5; +package cyclonedx.v1_5; // 1.5.1 import "google/protobuf/timestamp.proto"; // Specifies attributes of the text @@ -960,7 +960,7 @@ message VulnerabilityAffectedVersions { oneof choice { // A single version of a component or service. string version = 1; - // A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/purl-spec/VERSION-RANGE-SPEC.rst + // A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec string range = 2; } // The vulnerability status for the version or range of versions. Defaults to VULNERABILITY_AFFECTED_STATUS_AFFECTED if not specified. @@ -1009,6 +1009,8 @@ message ModelCard { optional QuantitativeAnalysis quantitativeAnalysis = 3; // What considerations should be taken into account regarding the model's construction, training, and application? optional ModelCardConsiderations considerations = 4; + // Specifies optional, custom, properties + repeated Property properties = 5; message ModelParameters { // The overall approach to learning used by the model for problem solving. diff --git a/schema/bom-1.5.schema.json b/schema/bom-1.5.schema.json index 3ecc1dcdb..d9c4d0803 100644 --- a/schema/bom-1.5.schema.json +++ b/schema/bom-1.5.schema.json @@ -2284,7 +2284,7 @@ "$ref": "#/definitions/version" }, "range": { - "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/purl-spec/VERSION-RANGE-SPEC.rst", + "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec", "$ref": "#/definitions/range" }, "status": { @@ -2326,7 +2326,7 @@ "maxLength": 1024 }, "range": { - "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/purl-spec/VERSION-RANGE-SPEC.rst", + "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec", "type": "string", "minLength": 1, "maxLength": 1024 diff --git a/schema/bom-1.5.xsd b/schema/bom-1.5.xsd index 94c238712..8a541afb0 100644 --- a/schema/bom-1.5.xsd +++ b/schema/bom-1.5.xsd @@ -22,7 +22,7 @@ limitations under the License. targetNamespace="http://cyclonedx.org/schema/bom/1.5" vc:minVersion="1.0" vc:maxVersion="1.1" - version="1.5.0"> + version="1.5.1"> @@ -2433,12 +2433,12 @@ limitations under the License. - The relationship is incomplete. Only relationships for third-party components, services, or their dependencies are represented, limited specifically to those that are proprietary. + The relationship is incomplete. Only relationships for first-party components, services, or their dependencies are represented, limited specifically to those that are proprietary. - The relationship is incomplete. Only relationships for third-party components, services, or their dependencies are represented, limited specifically to those that are opensource. + The relationship is incomplete. Only relationships for first-party components, services, or their dependencies are represented, limited specifically to those that are opensource. @@ -2885,7 +2885,7 @@ limitations under the License. - + @@ -2897,7 +2897,7 @@ limitations under the License. - + @@ -2911,7 +2911,7 @@ limitations under the License. - + @@ -2923,7 +2923,7 @@ limitations under the License. - + @@ -3008,6 +3008,16 @@ limitations under the License. + + + Provides the ability to document properties in a name/value store. + This provides flexibility to include data not officially supported in the standard + without having to use additional namespaces or create extensions. Property names + of interest to the general public are encouraged to be registered in the + CycloneDX Property Taxonomy - https://github.com/CycloneDX/cyclonedx-property-taxonomy. + Formal registration is OPTIONAL. + + @@ -3644,7 +3654,7 @@ limitations under the License. - A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/purl-spec/VERSION-RANGE-SPEC.rst + A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec diff --git a/schema/bom-1.6.proto b/schema/bom-1.6.proto index b6194c7e7..737a133af 100644 --- a/schema/bom-1.6.proto +++ b/schema/bom-1.6.proto @@ -4,7 +4,7 @@ import "google/protobuf/timestamp.proto"; // Specifies attributes of the text message AttachedText { - // Specifies the format and nature of the data being attached, helping systems correctly interpret and process the content. Common content type examples include `application/json` for JSON data and `text/plain` for plan text documents. [RFC 2045 section 5.1](https://www.ietf.org/rfc/rfc2045.html#section-5.1) outlines the structure and use of content types. For a comprehensive list of registered content types, refer to the [IANA media types registry](https://www.iana.org/assignments/media-types/media-types.xhtml). + // Specifies the format and nature of the data being attached, helping systems correctly interpret and process the content. Common content type examples include `application/json` for JSON data and `text/plain` for plain text documents. [RFC 2045 section 5.1](https://www.ietf.org/rfc/rfc2045.html#section-5.1) outlines the structure and use of content types. For a comprehensive list of registered content types, refer to the [IANA media types registry](https://www.iana.org/assignments/media-types/media-types.xhtml). optional string content_type = 1; // Specifies the optional encoding the text is represented in optional string encoding = 2; @@ -888,7 +888,7 @@ message Vulnerability { optional Source source = 3; // Zero or more pointers to vulnerabilities that are the equivalent of the vulnerability specified. Oftentimes, the same vulnerability may exist in multiple sources of vulnerability intelligence but have different identifiers. References provide a way to correlate vulnerabilities across multiple sources of vulnerability intelligence. repeated VulnerabilityReference references = 4; - // List of vulnerability ratings + // List of vulnerability ratings. Consumers SHOULD consider ratings in prioritization decisions; source ratings may differ and aid prioritization. repeated VulnerabilityRating ratings = 5; // List of Common Weaknesses Enumerations (CWEs) codes that describe this vulnerability. For example, 399 (of https://cwe.mitre.org/data/definitions/399.html) repeated int32 cwes = 6; @@ -1093,7 +1093,7 @@ message VulnerabilityAffectedVersions { oneof choice { // A single version of a component or service. string version = 1; - // A version range specified in Package URL Version Range syntax (vers), which is defined at https://github.com/package-url/purl-spec/VERSION-RANGE-SPEC.rst + // A version range specified in Package URL Version Range syntax (vers), which is defined at https://github.com/package-url/vers-spec string range = 2; } // The vulnerability status for the version or range of versions. Defaults to VULNERABILITY_AFFECTED_STATUS_AFFECTED if not specified. @@ -1152,6 +1152,8 @@ message ModelCard { optional QuantitativeAnalysis quantitativeAnalysis = 3; // What considerations should be taken into account regarding the model's construction, training, and application? optional ModelCardConsiderations considerations = 4; + // Specifies optional, custom, properties + repeated Property properties = 5; message ModelParameters { // The overall approach to learning used by the model for problem-solving. diff --git a/schema/bom-1.6.schema.json b/schema/bom-1.6.schema.json index 45fd8e20d..b6c096a99 100644 --- a/schema/bom-1.6.schema.json +++ b/schema/bom-1.6.schema.json @@ -25,7 +25,7 @@ "type": "string", "title": "CycloneDX Specification Version", "description": "The version of the CycloneDX specification the BOM conforms to.", - "examples": ["1.6.1"] + "examples": ["1.6"] }, "serialNumber": { "type": "string", @@ -536,7 +536,7 @@ "description": "Identifier for referable and therefore interlinkable elements.\nValue SHOULD not start with the BOM-Link intro 'urn:cdx:' to avoid conflicts with BOM-Links.", "type": "string", "minLength": 1, - "$comment": "TODO (breaking change): add a format constraint that prevents the value from staring with 'urn:cdx:'" + "$comment": "TODO (breaking change): add a format constraint that prevents the value from starting with 'urn:cdx:'" }, "refLinkType": { "description": "Descriptor for an element identified by the attribute 'bom-ref' in the same BOM document.\nIn contrast to `bomLinkElementType`.", @@ -1161,7 +1161,7 @@ "contentType": { "type": "string", "title": "Content-Type", - "description": "Specifies the format and nature of the data being attached, helping systems correctly interpret and process the content. Common content type examples include `application/json` for JSON data and `text/plain` for plan text documents.\n [RFC 2045 section 5.1](https://www.ietf.org/rfc/rfc2045.html#section-5.1) outlines the structure and use of content types. For a comprehensive list of registered content types, refer to the [IANA media types registry](https://www.iana.org/assignments/media-types/media-types.xhtml).", + "description": "Specifies the format and nature of the data being attached, helping systems correctly interpret and process the content. Common content type examples include `application/json` for JSON data and `text/plain` for plain text documents.\n [RFC 2045 section 5.1](https://www.ietf.org/rfc/rfc2045.html#section-5.1) outlines the structure and use of content types. For a comprehensive list of registered content types, refer to the [IANA media types registry](https://www.iana.org/assignments/media-types/media-types.xhtml).", "default": "text/plain", "examples": [ "text/plain", @@ -2237,7 +2237,7 @@ "aggregate": { "$ref": "#/definitions/aggregateType", "title": "Aggregate", - "description": "Specifies an aggregate type that describe how complete a relationship is." + "description": "Specifies an aggregate type that describes how complete a relationship is." }, "assemblies": { "type": "array", @@ -2681,7 +2681,7 @@ "ratings": { "type": "array", "title": "Ratings", - "description": "List of vulnerability ratings", + "description": "List of vulnerability ratings. Consumers SHOULD consider ratings in prioritization decisions; source ratings may differ and aid prioritization.", "items": { "$ref": "#/definitions/rating" } @@ -2928,7 +2928,7 @@ }, "range": { "title": "Version Range", - "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/purl-spec/VERSION-RANGE-SPEC.rst", + "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec", "$ref": "#/definitions/versionRange" }, "status": { @@ -2983,7 +2983,7 @@ ] }, "versionRange": { - "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/purl-spec/VERSION-RANGE-SPEC.rst", + "description": "A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec", "type": "string", "minLength": 1, "maxLength": 4096, diff --git a/schema/bom-1.6.xsd b/schema/bom-1.6.xsd index eae30ee47..4f7c2f914 100644 --- a/schema/bom-1.6.xsd +++ b/schema/bom-1.6.xsd @@ -76,7 +76,7 @@ limitations under the License. Specifies the format and nature of the data being attached, helping systems correctly interpret and process the content. Common content type examples include `application/json` - for JSON data and `text/plain` for plan text documents. + for JSON data and `text/plain` for plain text documents. RFC 2045 section 5.1 outlines the structure and use of content types. For a comprehensive list of registered content types, refer to the IANA media types registry at https://www.iana.org/assignments/media-types/media-types.xhtml. @@ -2672,7 +2672,7 @@ limitations under the License. - opyright evidence captures intellectual property assertions, providing evidence of possible ownership and legal protection. + Copyright evidence captures intellectual property assertions, providing evidence of possible ownership and legal protection. @@ -2715,7 +2715,7 @@ limitations under the License. - Specifies an aggregate type that describe how complete a relationship is. + Specifies an aggregate type that describes how complete a relationship is. @@ -2810,12 +2810,12 @@ limitations under the License. - The relationship is incomplete. Only relationships for third-party components, services, or their dependencies are represented, limited specifically to those that are proprietary. + The relationship is incomplete. Only relationships for first-party components, services, or their dependencies are represented, limited specifically to those that are proprietary. - The relationship is incomplete. Only relationships for third-party components, services, or their dependencies are represented, limited specifically to those that are opensource. + The relationship is incomplete. Only relationships for first-party components, services, or their dependencies are represented, limited specifically to those that are opensource. @@ -3256,7 +3256,7 @@ limitations under the License. - + @@ -3268,7 +3268,7 @@ limitations under the License. - + @@ -3282,7 +3282,7 @@ limitations under the License. - + @@ -3294,7 +3294,7 @@ limitations under the License. - + @@ -3386,6 +3386,16 @@ limitations under the License. + + + Provides the ability to document properties in a name/value store. + This provides flexibility to include data not officially supported in the standard + without having to use additional namespaces or create extensions. Property names + of interest to the general public are encouraged to be registered in the + CycloneDX Property Taxonomy - https://github.com/CycloneDX/cyclonedx-property-taxonomy. + Formal registration is OPTIONAL. + + @@ -4218,7 +4228,7 @@ limitations under the License. - List of vulnerability ratings. + List of vulnerability ratings. Consumers SHOULD consider ratings in prioritization decisions; source ratings may differ and aid prioritization. @@ -4475,7 +4485,7 @@ limitations under the License. - A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/purl-spec/VERSION-RANGE-SPEC.rst + A version range specified in Package URL Version Range syntax (vers) which is defined at https://github.com/package-url/vers-spec diff --git a/schema/xmlcatalog.xml b/schema/xmlcatalog.xml new file mode 100644 index 000000000..e250aa746 --- /dev/null +++ b/schema/xmlcatalog.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + From 89feacaddd220d59c9686ce6df56a71a7ebdd62f Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 19 May 2026 11:44:33 +0200 Subject: [PATCH 3/9] fix: back-port schema Signed-off-by: Jan Kowalleck --- schema/xmlcatalog.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/schema/xmlcatalog.xml b/schema/xmlcatalog.xml index e250aa746..7eae3fa9e 100644 --- a/schema/xmlcatalog.xml +++ b/schema/xmlcatalog.xml @@ -34,7 +34,6 @@ limitations under the License. - From 3c02631e1f0d5a11ab50420b870c95c3530bb8bb Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 19 May 2026 11:45:35 +0200 Subject: [PATCH 4/9] tests: backport test cases Signed-off-by: Jan Kowalleck --- .../1.5/valid-machine-learning-1.5.json | 24 ++- .../1.5/valid-machine-learning-1.5.textproto | 12 ++ .../1.5/valid-machine-learning-1.5.xml | 8 + ...id-license-declared-concluded-mix-1.6.json | 79 ++++++++++ ...lid-license-declared-concluded-mix-1.6.xml | 46 ++++++ .../resources/1.6/valid-annotation-1.6.json | 7 + .../1.6/valid-annotation-1.6.textproto | 20 +-- .../resources/1.6/valid-annotation-1.6.xml | 14 +- .../1.6/valid-attestation-1.6.textproto | 12 +- .../resources/1.6/valid-attestation-1.6.xml | 8 +- .../src/test/resources/1.6/valid-bom-1.6.json | 145 +++++++++++++++--- .../resources/1.6/valid-bom-1.6.textproto | 141 +++++++++++++---- .../src/test/resources/1.6/valid-bom-1.6.xml | 17 +- .../valid-component-identifiers-1.6.textproto | 2 +- .../1.6/valid-component-ref-1.6.json | 12 +- .../1.6/valid-component-ref-1.6.textproto | 8 +- .../resources/1.6/valid-compositions-1.6.xml | 8 +- .../1.6/valid-cryptography-full-1.6.json | 11 +- .../1.6/valid-cryptography-full-1.6.textproto | 37 +++-- .../1.6/valid-cryptography-full-1.6.xml | 24 +++ .../valid-cryptography-implementation-1.6.xml | 4 +- .../resources/1.6/valid-dependency-1.6.xml | 6 +- .../1.6/valid-evidence-1.6.textproto | 1 - .../1.6/valid-external-reference-1.6.xml | 3 +- .../resources/1.6/valid-formulation-1.6.json | 4 +- .../1.6/valid-formulation-1.6.textproto | 43 +++--- .../resources/1.6/valid-formulation-1.6.xml | 12 +- .../1.6/valid-license-expression-1.6.json | 25 ++- .../valid-license-expression-1.6.textproto | 21 ++- .../1.6/valid-license-expression-1.6.xml | 4 +- .../resources/1.6/valid-license-id-1.6.json | 25 ++- .../1.6/valid-license-id-1.6.textproto | 22 ++- .../resources/1.6/valid-license-name-1.6.json | 25 ++- .../1.6/valid-license-name-1.6.textproto | 22 ++- .../1.6/valid-machine-learning-1.6.json | 25 ++- .../1.6/valid-machine-learning-1.6.textproto | 29 +++- .../1.6/valid-machine-learning-1.6.xml | 12 +- ...achine-learning-considerations-env-1.6.xml | 2 +- .../valid-metadata-timestamp-1.6.textproto | 4 +- .../1.6/valid-metadata-timestamp-1.6.xml | 2 +- .../1.6/valid-release-notes-1.6.json | 6 +- .../1.6/valid-release-notes-1.6.textproto | 54 ++++++- .../resources/1.6/valid-release-notes-1.6.xml | 4 +- .../test/resources/1.6/valid-saasbom-1.6.json | 2 +- .../resources/1.6/valid-saasbom-1.6.textproto | 58 +++++-- .../test/resources/1.6/valid-saasbom-1.6.xml | 33 ++-- .../test/resources/1.6/valid-service-1.6.json | 2 +- .../resources/1.6/valid-service-1.6.textproto | 2 +- .../test/resources/1.6/valid-service-1.6.xml | 5 +- .../1.6/valid-standard-1.6.textproto | 2 +- .../1.6/valid-vulnerability-1.6.textproto | 26 ++-- .../resources/1.6/valid-vulnerability-1.6.xml | 11 +- 52 files changed, 894 insertions(+), 237 deletions(-) create mode 100644 tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.json create mode 100644 tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.xml diff --git a/tools/src/test/resources/1.5/valid-machine-learning-1.5.json b/tools/src/test/resources/1.5/valid-machine-learning-1.5.json index 59dc3ceef..f16696aff 100644 --- a/tools/src/test/resources/1.5/valid-machine-learning-1.5.json +++ b/tools/src/test/resources/1.5/valid-machine-learning-1.5.json @@ -60,16 +60,20 @@ }, "considerations": { "users": [ - "Who are the intended users of the model?" + "Who are the intended users of the model?", + "Data scientists and ML researchers" ], "useCases": [ - "Who are the intended users of the model?" + "Who are the intended users of the model?", + "Text-to-image generation for creative applications" ], "technicalLimitations": [ - "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" + "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?", + "Limited performance on non-photographic styles" ], "performanceTradeoffs": [ - "What are the known tradeoffs in accuracy/performance of the model?" + "What are the known tradeoffs in accuracy/performance of the model?", + "Higher resolution output requires more computational resources" ], "ethicalConsiderations": [ { @@ -85,7 +89,17 @@ "mitigationStrategy": "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." } ] - } + }, + "properties": [ + { + "name": "modelcard:custom-property", + "value": "custom-value" + }, + { + "name": "modelcard:another-custom-property", + "value": "another-custom-value" + } + ] } } ] diff --git a/tools/src/test/resources/1.5/valid-machine-learning-1.5.textproto b/tools/src/test/resources/1.5/valid-machine-learning-1.5.textproto index 4e54321d7..a7e6e0d38 100644 --- a/tools/src/test/resources/1.5/valid-machine-learning-1.5.textproto +++ b/tools/src/test/resources/1.5/valid-machine-learning-1.5.textproto @@ -48,9 +48,13 @@ components { } considerations: { users: "Who are the intended users of the model?" + users: "Data scientists and ML researchers" useCases: "Who are the intended users of the model?" + useCases: "Text-to-image generation for creative applications" technicalLimitations: "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" + technicalLimitations: "Limited performance on non-photographic styles" performanceTradeoffs: "What are the known tradeoffs in accuracy/performance of the model?" + performanceTradeoffs: "Higher resolution output requires more computational resources" ethicalConsiderations: { name: "The name of the risk" mitigationStrategy: "Strategy used to address this risk" @@ -62,5 +66,13 @@ components { mitigationStrategy: "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." } } + properties: { + name: "modelcard:custom-property" + value: "custom-value" + } + properties: { + name: "modelcard:another-custom-property" + value: "another-custom-value" + } } } diff --git a/tools/src/test/resources/1.5/valid-machine-learning-1.5.xml b/tools/src/test/resources/1.5/valid-machine-learning-1.5.xml index 7c541ecb8..6756ccb7f 100644 --- a/tools/src/test/resources/1.5/valid-machine-learning-1.5.xml +++ b/tools/src/test/resources/1.5/valid-machine-learning-1.5.xml @@ -61,15 +61,19 @@ Who are the intended users of the model? + Data scientists and ML researchers Who are the intended users of the model? + Text-to-image generation for creative applications What are the known technical limitations of the model? + Limited performance on non-photographic styles What are the known tradeoffs in accuracy/performance of the model? + Higher resolution output requires more computational resources @@ -86,6 +90,10 @@ + + custom-value + another-custom-value + diff --git a/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.json b/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.json new file mode 100644 index 000000000..7c6813c1b --- /dev/null +++ b/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.json @@ -0,0 +1,79 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:df628836-6b9b-41c9-a724-b44743c54d42", + "version": 1, + "metadata": { + "lifecycles": [{"phase": "design"}] + }, + "components": [ + { + "type": "library", + "group": "com.example", + "name": "situation-A", + "version": "1", + "description": "Multiple licenses: declared ids/names, and a concluded expression", + "licenses": [ + { + "license": { + "id": "MIT", + "acknowledgement": "declared" + } + }, + { + "license": { + "id": "PostgreSQL", + "acknowledgement": "declared" + } + }, + { + "license": { + "name": "Apache Software License", + "acknowledgement": "declared" + } + }, + { + "expression": "(MIT OR PostgreSQL OR Apache-2.0)", + "acknowledgement": "concluded" + } + ] + }, + { + "type": "library", + "group": "com.example", + "name": "situation-B", + "version": "1", + "description": "Multiple license expressions: one declared, one concluded", + "licenses": [ + { + "expression": "MIT OR (GPL-3.0 OR GPL-2.0)", + "acknowledgement": "declared" + }, + { + "expression": "(GPL-3.0-only AND LGPL-2.0-only)", + "acknowledgement": "concluded" + } + ] + }, + { + "type": "library", + "group": "com.example", + "name": "situation-C", + "version": "1", + "description": "Multiple license: one declared expression, one concluded id", + "licenses": [ + { + "expression": "GPL-3.0-or-later OR GPL-2.0", + "acknowledgement": "declared" + }, + { + "license": { + "id": "GPL-3.0-only", + "acknowledgement": "concluded" + } + } + ] + } + ] +} diff --git a/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.xml b/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.xml new file mode 100644 index 000000000..849ad97b9 --- /dev/null +++ b/tools/src/test/resources/1.6/invalid-license-declared-concluded-mix-1.6.xml @@ -0,0 +1,46 @@ + + + + + design + + + + com.example + situation-A + 1 + Multiple licenses: declared ids/names, and a concluded expression + + MIT + PostgreSQL + Apache Software License + (MIT OR PostgreSQL OR Apache-2.0) + + + + com.example + situation-B + 1 + Multiple license expressions: one declared, one concluded + + MIT OR (GPL-3.0 OR GPL-2.0) + (GPL-3.0-only AND LGPL-2.0-only) + + + + com.example + situation-C + 1 + Multiple license: one declared expression, one concluded id + + GPL-3.0-or-later OR GPL-2.0 + GPL-3.0-only + + + + diff --git a/tools/src/test/resources/1.6/valid-annotation-1.6.json b/tools/src/test/resources/1.6/valid-annotation-1.6.json index b0e8ec7d9..108d5ed8d 100644 --- a/tools/src/test/resources/1.6/valid-annotation-1.6.json +++ b/tools/src/test/resources/1.6/valid-annotation-1.6.json @@ -77,6 +77,13 @@ "name": "Partner Org", "url": [ "https://partner.org" + ], + "contact" : [ + { + "name": "Support", + "email": "support@partner.org", + "phone": "800-555-1212" + } ] }, "group": "org.partner", diff --git a/tools/src/test/resources/1.6/valid-annotation-1.6.textproto b/tools/src/test/resources/1.6/valid-annotation-1.6.textproto index 65eb21ede..8db977180 100644 --- a/tools/src/test/resources/1.6/valid-annotation-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-annotation-1.6.textproto @@ -24,8 +24,8 @@ annotations { } } timestamp { - seconds: 3173618478 - nanos: 3 + seconds: 1640995200 + nanos: 0 } text: "This is a sample annotation made by an organization" } @@ -40,10 +40,10 @@ annotations { } } timestamp { - seconds: 3173618478 - nanos: 3 + seconds: 1640995200 + nanos: 0 } - text: "This is a sample annotation made by an person" + text: "This is a sample annotation made by a person" } annotations { bom_ref: "annotation-3" @@ -56,8 +56,8 @@ annotations { } } timestamp { - seconds: 3173618478 - nanos: 3 + seconds: 1640995200 + nanos: 0 } text: "This is a sample annotation made by a component" } @@ -72,7 +72,7 @@ annotations { url: "https://partner.org" contact { name: "Support" - email: "support@partner" + email: "support@partner.org" phone: "800-555-1212" } } @@ -90,8 +90,8 @@ annotations { } } timestamp { - seconds: 3173618478 - nanos: 3 + seconds: 1640995200 + nanos: 0 } text: "This is a sample annotation made by a service" } diff --git a/tools/src/test/resources/1.6/valid-annotation-1.6.xml b/tools/src/test/resources/1.6/valid-annotation-1.6.xml index ea3c28728..c329a23c1 100644 --- a/tools/src/test/resources/1.6/valid-annotation-1.6.xml +++ b/tools/src/test/resources/1.6/valid-annotation-1.6.xml @@ -21,7 +21,7 @@ - 2020-04-07T07:01:00Z + 2022-01-01T00:00:00Z This is a sample annotation made by an organization @@ -35,8 +35,8 @@ 800-555-1212 - 2020-04-07T07:01:00Z - This is a sample annotation made by an person + 2022-01-01T00:00:00Z + This is a sample annotation made by a person @@ -48,7 +48,7 @@ 9.1.2 - 2020-04-07T07:01:00Z + 2022-01-01T00:00:00Z This is a sample annotation made by a component @@ -62,7 +62,7 @@ https://partner.org Support - support@partner + support@partner.org 800-555-1212 @@ -76,11 +76,11 @@ true true - pubic + public - 2020-04-07T07:01:00Z + 2022-01-01T00:00:00Z This is a sample annotation made by a service diff --git a/tools/src/test/resources/1.6/valid-attestation-1.6.textproto b/tools/src/test/resources/1.6/valid-attestation-1.6.textproto index 163213085..0909b277d 100644 --- a/tools/src/test/resources/1.6/valid-attestation-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-attestation-1.6.textproto @@ -72,11 +72,11 @@ declarations: { } ] created { - seconds: 1714003200 + seconds: 1682380800 nanos: 0 } expires { - seconds: 1712102400 + seconds: 1684972800 nanos: 0 } author: { @@ -104,11 +104,11 @@ declarations: { } ] created { - seconds: 1714003200 + seconds: 1682380800 nanos: 0 } expires { - seconds: 1712102400 + seconds: 1684972800 nanos: 0 } author: { @@ -136,11 +136,11 @@ declarations: { } ] created { - seconds: 1714003200 + seconds: 1682380800 nanos: 0 } expires { - seconds: 1712102400 + seconds: 1684972800 nanos: 0 } author: { diff --git a/tools/src/test/resources/1.6/valid-attestation-1.6.xml b/tools/src/test/resources/1.6/valid-attestation-1.6.xml index 1dce0ced8..4f34748a0 100644 --- a/tools/src/test/resources/1.6/valid-attestation-1.6.xml +++ b/tools/src/test/resources/1.6/valid-attestation-1.6.xml @@ -3,9 +3,9 @@ - false + true - Acme Inc + Assessors Inc @@ -25,7 +25,7 @@ 0.8 Conformance rationale here - mitigations-1 + mitigationStrategy-1 @@ -110,7 +110,7 @@ Mitigation strategy here - Public + Company Confidential Describe sensitive data here 2023-04-25T00:00:00+00:00 diff --git a/tools/src/test/resources/1.6/valid-bom-1.6.json b/tools/src/test/resources/1.6/valid-bom-1.6.json index c07ab7b0c..9ab00e7bb 100644 --- a/tools/src/test/resources/1.6/valid-bom-1.6.json +++ b/tools/src/test/resources/1.6/valid-bom-1.6.json @@ -73,13 +73,15 @@ }, "components": [ { - "bom-ref": "pkg:npm/acme/component@1.0.0", - "type": "library", + "bom-ref": "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar", + "type": "application", "author": "Joane Doe et al.", "publisher": "Acme Inc", "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", + "description": "Modified version of Apache Catalina", + "scope": "required", "hashes": [ { "alg": "MD5", @@ -105,28 +107,31 @@ "text": { "contentType": "text/plain", "encoding": "base64", - "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" }, "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" } } ], - "purl": "pkg:npm/acme/component@1.0.0", + "purl": "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar", "pedigree": { "ancestors": [ { - "type": "library", - "publisher": "Acme Inc", - "group": "com.acme", - "name": "tomcat-catalina", - "version": "9.0.14" - }, - { - "type": "library", - "publisher": "Acme Inc", - "group": "com.acme", + "type": "application", + "author": "Apache Super Heros", + "publisher": "Apache", + "group": "org.apache.tomcat", "name": "tomcat-catalina", - "version": "9.0.14" + "version": "9.0.14", + "description": "Apache Catalina", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "purl": "pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar" } ], "commits": [ @@ -135,15 +140,23 @@ "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", "author": { "timestamp": "2018-11-13T20:20:39+00:00", - "name": "me", - "email": "me@acme.org" - } + "name": "John Doe", + "email": "john.doe@example.com" + }, + "committer": { + "timestamp": "2018-11-07T22:01:45Z", + "name": "Jane Doe", + "email": "jane.doe@example.com" + }, + "message": "Initial commit" } - ] + ], + "notes": "Commentary here" } }, { "type": "library", + "bom-ref": "pkg:maven/com.example/myapplication@1.0.0?packaging=war", "supplier": { "name": "Example, Inc.", "url": [ @@ -152,7 +165,7 @@ ], "contact": [ { - "name": "Example Support AMER Distribution", + "name": "Example Support AMER", "email": "support@example.com", "phone": "800-555-1212" }, @@ -187,15 +200,99 @@ "group": "org.example", "name": "mylibrary", "version": "1.0.0", - "scope": "required" + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "2342c2eaf1feb9a80195dbaddf2ebaa3" + }, + { + "alg": "SHA-1", + "content": "68b78babe00a053f9e35ec6a2d9080f5b90122b0" + }, + { + "alg": "SHA-256", + "content": "708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313" + }, + { + "alg": "SHA-512", + "content": "387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef" + } + ], + "licenses": [ + { + "expression": "EPL-2.0 OR GPL-2.0-with-classpath-exception" + } + ], + "copyright": "Copyright Example Inc. All rights reserved.", + "cpe": "cpe:/a:example:myapplication:1.0.0", + "purl": "pkg:maven/com.example/myapplication@1.0.0?packaging=war", + "modified": false, + "externalReferences": [ + { + "url": "http://example.org/docs", + "type": "documentation", + "comment": "All component versions are documented here" + }, + { + "url": "http://example.org/security", + "type": "advisories" + } + ] + }, + { + "type": "framework", + "author": "Example Super Heros", + "group": "com.example", + "name": "myframework", + "version": "1.0.0", + "description": "Example Inc, enterprise framework", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "cfcb0b64aacd2f81c1cd546543de965a" + }, + { + "alg": "SHA-1", + "content": "7fbeef2346c45d565c3341f037bce4e088af8a52" + }, + { + "alg": "SHA-256", + "content": "0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1" + }, + { + "alg": "SHA-512", + "content": "854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79" + } + ], + "licenses": [ + { + "license": { + "name": "Some random license" + } + } + ], + "purl": "pkg:maven/com.example/myframework@1.0.0?packaging=war", + "modified": false, + "externalReferences": [ + { + "type": "website", + "url": "http://example.com/myframework" + }, + { + "type": "advisories", + "url": "http://example.com/security" + } + ] } ], "dependencies": [ { - "ref": "pkg:npm/acme/component@1.0.0", + "ref": "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar", "dependsOn": [ - "pkg:npm/acme/component@1.0.0" + "pkg:maven/com.example/myapplication@1.0.0?packaging=war" ] } ] -} +} \ No newline at end of file diff --git a/tools/src/test/resources/1.6/valid-bom-1.6.textproto b/tools/src/test/resources/1.6/valid-bom-1.6.textproto index 3d7937071..7338519cb 100644 --- a/tools/src/test/resources/1.6/valid-bom-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-bom-1.6.textproto @@ -6,8 +6,8 @@ version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" metadata { timestamp { - seconds: 3173618478 - nanos: 3 + seconds: 1586809239 + nanos: 0 } tools { vendor: "Awesome Vendor" @@ -61,13 +61,15 @@ metadata { } } components { - type: CLASSIFICATION_LIBRARY - bom_ref: "pkg:npm/acme/component@1.0.0" + type: CLASSIFICATION_APPLICATION + bom_ref: "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar" author: "Joane Doe et al." publisher: "Acme Inc" group: "com.acme" name: "tomcat-catalina" version: "9.0.14" + description: "Modified version of Apache Catalina" + scope: SCOPE_REQUIRED hashes { alg: HASH_ALG_MD_5 value: "3942447fac867ae5cdb3229b658f4d48" @@ -90,49 +92,61 @@ components { text { content_type: "text/plain" encoding: "base64" - value: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + value: "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" } url: "https://www.apache.org/licenses/LICENSE-2.0.txt" } } - purl: "pkg:npm/acme/component@1.0.0" + purl: "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar" pedigree { ancestors { - type: CLASSIFICATION_LIBRARY - publisher: "Acme Inc" - group: "com.acme" - name: "tomcat-catalina" - version: "9.0.14" - } - ancestors { - type: CLASSIFICATION_LIBRARY - publisher: "Acme Inc" - group: "com.acme" + type: CLASSIFICATION_APPLICATION + author: "Apache Super Heros" + publisher: "Apache" + group: "org.apache.tomcat" name: "tomcat-catalina" version: "9.0.14" + description: "Apache Catalina" + licenses { + license { + id: "Apache-2.0" + } + } + purl: "pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar" } commits { - uid: "123" - url: "" + uid: "7638417db6d59f3c431d3e1f261cc637155684cd" + url: "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd" author { timestamp { - seconds: 3084280878 - nanos: 3 + seconds: 1542140439 + nanos: 0 + } + name: "John Doe" + email: "john.doe@example.com" + } + committer { + timestamp { + seconds: 1541628105 + nanos: 0 } - name: "" - email: "" + name: "Jane Doe" + email: "jane.doe@example.com" } + message: "Initial commit" } + notes: "Commentary here" } } components { type: CLASSIFICATION_LIBRARY + bom_ref: "pkg:maven/com.example/myapplication@1.0.0?packaging=war" supplier { name: "Example, Inc." url: "https://example.com" url: "https://example.net" contact { - name: "Example Support AMER Distribution" + name: "Example Support AMER" email: "support@example.com" phone: "800-555-1212" } @@ -141,11 +155,44 @@ components { email: "support@apac.example.com" } } - author: "Example Super Heros" group: "org.example" name: "mylibrary" version: "1.0.0" scope: SCOPE_REQUIRED + hashes { + alg: HASH_ALG_MD_5 + value: "2342c2eaf1feb9a80195dbaddf2ebaa3" + } + hashes { + alg: HASH_ALG_SHA_1 + value: "68b78babe00a053f9e35ec6a2d9080f5b90122b0" + } + hashes { + alg: HASH_ALG_SHA_256 + value: "708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313" + } + hashes { + alg: HASH_ALG_SHA_512 + value: "387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef" + } + licenses { + expression: "EPL-2.0 OR GPL-2.0-with-classpath-exception" + } + copyright: "Copyright Example Inc. All rights reserved." + cpe: "cpe:/a:example:myapplication:1.0.0" + purl: "pkg:maven/com.example/myapplication@1.0.0?packaging=war" + modified: false + external_references: [ + { + url: "http://example.org/docs" + type: EXTERNAL_REFERENCE_TYPE_DOCUMENTATION + comment: "All component versions are documented here" + }, + { + url: "http://example.org/security" + type: EXTERNAL_REFERENCE_TYPE_ADVISORIES + } + ] manufacturer { name: "Example-2, Inc." url: "https://example.org" @@ -163,9 +210,51 @@ components { email: "spiderman@example.org" } } +components { + type: CLASSIFICATION_FRAMEWORK + author: "Example Super Heros" + group: "com.example" + name: "myframework" + version: "1.0.0" + description: "Example Inc, enterprise framework" + scope: SCOPE_REQUIRED + hashes { + alg: HASH_ALG_MD_5 + value: "cfcb0b64aacd2f81c1cd546543de965a" + } + hashes { + alg: HASH_ALG_SHA_1 + value: "7fbeef2346c45d565c3341f037bce4e088af8a52" + } + hashes { + alg: HASH_ALG_SHA_256 + value: "0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1" + } + hashes { + alg: HASH_ALG_SHA_512 + value: "854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79" + } + licenses { + license { + name: "Some random license" + } + } + purl: "pkg:maven/com.example/myframework@1.0.0?packaging=war" + modified: false + external_references: [ + { + url: "http://example.com/myframework" + type: EXTERNAL_REFERENCE_TYPE_WEBSITE + }, + { + url: "http://example.com/security" + type: EXTERNAL_REFERENCE_TYPE_ADVISORIES + } + ] +} dependencies { - ref: "pkg:npm/acme/component@1.0.0" + ref: "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar" dependencies { - ref: "pkg:npm/acme/component@1.0.0" + ref: "pkg:maven/com.example/myapplication@1.0.0?packaging=war" } } diff --git a/tools/src/test/resources/1.6/valid-bom-1.6.xml b/tools/src/test/resources/1.6/valid-bom-1.6.xml index 6760b9da0..5f94ce13b 100644 --- a/tools/src/test/resources/1.6/valid-bom-1.6.xml +++ b/tools/src/test/resources/1.6/valid-bom-1.6.xml @@ -1,7 +1,7 @@ - 2020-04-07T07:01:00Z + 2020-04-13T20:20:39+00:00 Awesome Vendor @@ -46,7 +46,7 @@ - + Joane Doe et al. Acme Inc com.acme @@ -90,7 +90,7 @@ 7638417db6d59f3c431d3e1f261cc637155684cd https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd - 2018-11-07T22:01:45Z + 2018-11-13T20:20:39+00:00 John Doe john.doe@example.com @@ -105,9 +105,9 @@ Commentary here - + - Example Inc. + Example, Inc. https://example.com https://example.net @@ -121,7 +121,7 @@ - Example-2, Inc.Example-2, Inc. + Example-2, Inc. https://example.org support@example.org @@ -195,4 +195,9 @@ + + + + + diff --git a/tools/src/test/resources/1.6/valid-component-identifiers-1.6.textproto b/tools/src/test/resources/1.6/valid-component-identifiers-1.6.textproto index 26ffb8e26..46d4fd9f0 100644 --- a/tools/src/test/resources/1.6/valid-component-identifiers-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-component-identifiers-1.6.textproto @@ -7,7 +7,7 @@ serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" components { type: CLASSIFICATION_LIBRARY group: "com.example" - name: "acme-example" + name: "acme-library" version: "1.0.0" cpe: "cpe:2.3:a:example:acme-library:1.0.0:*:*:*:*:*:*:*" purl: "pkg:maven/com.example/acme-library@1.0.0" diff --git a/tools/src/test/resources/1.6/valid-component-ref-1.6.json b/tools/src/test/resources/1.6/valid-component-ref-1.6.json index 73cf35cf5..c31d31e5f 100644 --- a/tools/src/test/resources/1.6/valid-component-ref-1.6.json +++ b/tools/src/test/resources/1.6/valid-component-ref-1.6.json @@ -9,11 +9,19 @@ "type": "library", "bom-ref": "123", "name": "acme-library", - "version": "1.0.0" + "version": "1.0.0", + "components" : [ + { + "type": "library", + "bom-ref": "456", + "name": "acme-library", + "version": "1.0.0" + } + ] }, { "type": "library", - "bom-ref": "456", + "bom-ref": "789", "name": "acme-library", "version": "1.0.0" } diff --git a/tools/src/test/resources/1.6/valid-component-ref-1.6.textproto b/tools/src/test/resources/1.6/valid-component-ref-1.6.textproto index 773a2decf..82060a83d 100644 --- a/tools/src/test/resources/1.6/valid-component-ref-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-component-ref-1.6.textproto @@ -9,10 +9,16 @@ components { bom_ref: "123" name: "acme-library" version: "1.0.0" + components { + type: CLASSIFICATION_LIBRARY + bom_ref: "456" + name: "acme-library" + version: "1.0.0" + } } components { type: CLASSIFICATION_LIBRARY - bom_ref: "456" + bom_ref: "789" name: "acme-library" version: "1.0.0" } diff --git a/tools/src/test/resources/1.6/valid-compositions-1.6.xml b/tools/src/test/resources/1.6/valid-compositions-1.6.xml index 5f8a76d01..f99ed8303 100644 --- a/tools/src/test/resources/1.6/valid-compositions-1.6.xml +++ b/tools/src/test/resources/1.6/valid-compositions-1.6.xml @@ -21,7 +21,7 @@ Acme Library - 2.0 + 3.0 pkg:maven/acme/library@3.0 @@ -49,9 +49,9 @@ incomplete_first_party_only - - - + + + diff --git a/tools/src/test/resources/1.6/valid-cryptography-full-1.6.json b/tools/src/test/resources/1.6/valid-cryptography-full-1.6.json index ac1344659..40e97a20a 100644 --- a/tools/src/test/resources/1.6/valid-cryptography-full-1.6.json +++ b/tools/src/test/resources/1.6/valid-cryptography-full-1.6.json @@ -65,7 +65,16 @@ "0xC0" ] } - ] + ], + "ikev2TransformTypes": { + "encr": ["bom-ref-to-encr"], + "prf": ["bom-ref-to-prf"], + "integ": ["bom-ref-to-integ"], + "ke": ["bom-ref-to-ke"], + "esn": true, + "auth": ["bom-ref-to-auth"] + }, + "cryptoRefArray": ["asset-4"] }, "oid": "oid:1.2.3.4.5.6.7.8.9" } diff --git a/tools/src/test/resources/1.6/valid-cryptography-full-1.6.textproto b/tools/src/test/resources/1.6/valid-cryptography-full-1.6.textproto index 904848c78..c2f31f8b9 100644 --- a/tools/src/test/resources/1.6/valid-cryptography-full-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-cryptography-full-1.6.textproto @@ -17,7 +17,7 @@ components: [ curve: "brainpoolP160r1" executionEnvironment: CRYPTO_EXECUTION_ENVIRONMENT_SOFTWARE_PLAIN_RAM implementationPlatform: CRYPTO_IMPLEMENTATION_PLATFORM_X86_64 - certificationLevel: [ "fips140-1-l4" ] + certificationLevel: ["fips140-1-l4"] mode: CRYPTO_ALGORITHM_MODE_GCM padding: CRYPTO_ALGORITHM_PADDING_PKCS5 cryptoFunctions: [ @@ -42,19 +42,19 @@ components: [ subjectName: "Subject name here" issuerName: "Issuer name here" notValidBefore { - seconds: 3173618478 - nanos: 3 + seconds: 1640995200 + nanos: 0 } notValidAfter { - seconds: 3173618478 - nanos: 3 + seconds: 1704067200 + nanos: 0 } signatureAlgorithmRef: "bom-ref-to-algorithm" subjectPublicKeyRef: "bom-ref-to-public-key" certificateFormat: "X.509" certificateExtension: "crt" } - oid: "oid:1.2.3.4.5.6.7.8.9" + oid: "oid:1.2.3.4.5.6.7.8.9" } }, { @@ -77,6 +77,15 @@ components: [ ] } ] + ikev2TransformTypes: { + encr: "bom-ref-to-encr" + prf: "bom-ref-to-prf" + integ: "bom-ref-to-integ" + ke: "bom-ref-to-ke" + esn: true + auth: "bom-ref-to-auth" + } + cryptoRef: "asset-4" } oid: "oid:1.2.3.4.5.6.7.8.9" } @@ -93,20 +102,20 @@ components: [ state: CRYPTO_RELATED_STATE_ACTIVE algorithmRef: "bom-ref-to-algorithm" creationDate { - seconds: 3173618478 - nanos: 3 + seconds: 1704067200 + nanos: 0 } activationDate { - seconds: 3173618478 - nanos: 3 + seconds: 1704153600 + nanos: 0 } updateDate { - seconds: 3173618478 - nanos: 3 + seconds: 1704240000 + nanos: 0 } expirationDate { - seconds: 3173618478 - nanos: 3 + seconds: 1704326400 + nanos: 0 } value: "Value here" size: 1024 diff --git a/tools/src/test/resources/1.6/valid-cryptography-full-1.6.xml b/tools/src/test/resources/1.6/valid-cryptography-full-1.6.xml index 0e151a343..624e228e8 100644 --- a/tools/src/test/resources/1.6/valid-cryptography-full-1.6.xml +++ b/tools/src/test/resources/1.6/valid-cryptography-full-1.6.xml @@ -40,6 +40,30 @@ X.509 crt + + tls + 1.3 + + + TLS_DHE_RSA_WITH_AES_128_CCM + + bom-ref-to-algorithm + + + 0xC0 + + + + + bom-ref-to-encr + bom-ref-to-prf + bom-ref-to-integ + bom-ref-to-ke + true + bom-ref-to-auth + + asset-4 + oid:1.2.3.4.5.6.7.8.9 diff --git a/tools/src/test/resources/1.6/valid-cryptography-implementation-1.6.xml b/tools/src/test/resources/1.6/valid-cryptography-implementation-1.6.xml index d9c97fee5..e86ae5940 100644 --- a/tools/src/test/resources/1.6/valid-cryptography-implementation-1.6.xml +++ b/tools/src/test/resources/1.6/valid-cryptography-implementation-1.6.xml @@ -31,11 +31,11 @@ - Crypto Library + Crypto library 1.0.0 - Some Library + Some library 1.0.0 diff --git a/tools/src/test/resources/1.6/valid-dependency-1.6.xml b/tools/src/test/resources/1.6/valid-dependency-1.6.xml index 903670cf0..7fab83476 100644 --- a/tools/src/test/resources/1.6/valid-dependency-1.6.xml +++ b/tools/src/test/resources/1.6/valid-dependency-1.6.xml @@ -2,15 +2,15 @@ - acme-library-a + library-a 1.0.0 - acme-library-b + library-b 1.0.0 - acme-library-b + library-c 1.0.0 diff --git a/tools/src/test/resources/1.6/valid-evidence-1.6.textproto b/tools/src/test/resources/1.6/valid-evidence-1.6.textproto index 216e9bb5c..e4819eb0f 100644 --- a/tools/src/test/resources/1.6/valid-evidence-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-evidence-1.6.textproto @@ -42,7 +42,6 @@ components [ } ], tools: [ - "bom-ref-of-tool-that-performed-analysis", "bom-ref-of-tool-that-performed-analysis" ] }, diff --git a/tools/src/test/resources/1.6/valid-external-reference-1.6.xml b/tools/src/test/resources/1.6/valid-external-reference-1.6.xml index f30782f79..95cffa0d2 100644 --- a/tools/src/test/resources/1.6/valid-external-reference-1.6.xml +++ b/tools/src/test/resources/1.6/valid-external-reference-1.6.xml @@ -2,6 +2,7 @@ + Acme Inc org.example mylibrary 1.0.0 @@ -14,7 +15,7 @@ https://example.org/support/sbom/portal-server/1.0.0 An external SBOM that describes what this component includes - f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 diff --git a/tools/src/test/resources/1.6/valid-formulation-1.6.json b/tools/src/test/resources/1.6/valid-formulation-1.6.json index 26a9a4b68..ce49ece6d 100644 --- a/tools/src/test/resources/1.6/valid-formulation-1.6.json +++ b/tools/src/test/resources/1.6/valid-formulation-1.6.json @@ -246,10 +246,10 @@ } ], "timeStart": "2023-01-01T00:00:00+00:00", - "timeEnd": "2023-01-01T00:00:00+10:00", + "timeEnd": "2023-01-01T00:00:10+00:00", "workspaces": [ { - "bom-ref": "workspace-1", + "bom-ref": "workspace-2", "uid": "workspace-1", "name": "My workspace", "aliases": [ "default-workspace" ], diff --git a/tools/src/test/resources/1.6/valid-formulation-1.6.textproto b/tools/src/test/resources/1.6/valid-formulation-1.6.textproto index e7deb4abb..7d71e3419 100644 --- a/tools/src/test/resources/1.6/valid-formulation-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-formulation-1.6.textproto @@ -38,7 +38,6 @@ formulation: [ bom_ref: "task-1" uid: "task-uid-1" name: "fetch-repository" - taskTypes: [ TASK_TYPE_CLONE ] description: "Description here" resourceReferences: [ { @@ -68,17 +67,17 @@ formulation: [ outputs: [ { resource: { - ref: "component-a" + ref: "component-b" } } ] timeStart { - seconds: 3173618478 - nanos: 3 + seconds: 1672531200 + nanos: 0 } timeEnd { - seconds: 3173618478 - nanos: 3 + seconds: 1672531200 + nanos: 0 } workspaces: [ { @@ -120,13 +119,13 @@ formulation: [ ref: "component-a" } ] - type: TRIGGER_TYPE_WEBHOOK + type: TRIGGER_TYPE_API event: { uid: "event-1" description: "Description here" timeReceived { - seconds: 3173618478 - nanos: 3 + seconds: 1672531200 + nanos: 0 } data: { content_type: "text/plain" @@ -158,8 +157,8 @@ formulation: [ } ] timeActivated { - seconds: 3173618478 - nanos: 3 + seconds: 1672531200 + nanos: 0 } inputs: [ { @@ -188,13 +187,13 @@ formulation: [ } } ] + properties: [ + { + name: "Foo" + value: "Bar" + } + ] } - properties: [ - { - name: "Foo" - value: "Bar" - } - ] steps: [ { name: "My step" @@ -283,16 +282,16 @@ formulation: [ } ] timeStart { - seconds: 3173618478 - nanos: 3 + seconds: 1672531200 + nanos: 0 } timeEnd { - seconds: 3173618478 - nanos: 3 + seconds: 1672531210 + nanos: 0 } workspaces: [ { - bom_ref: "workspace-1" + bom_ref: "workspace-2" uid: "workspace-1" name: "My workspace" aliases: [ "default-workspace" ] diff --git a/tools/src/test/resources/1.6/valid-formulation-1.6.xml b/tools/src/test/resources/1.6/valid-formulation-1.6.xml index 7f500a337..384418253 100644 --- a/tools/src/test/resources/1.6/valid-formulation-1.6.xml +++ b/tools/src/test/resources/1.6/valid-formulation-1.6.xml @@ -72,8 +72,8 @@ - - + + @@ -84,11 +84,11 @@ - clean + clone build - trigger-uid-1 + trigger-uid-2 My trigger Description here @@ -101,7 +101,7 @@ event-1 Description here 2023-01-01T00:00:00+00:00 - FooBar + Foo/Bar component-g @@ -207,7 +207,7 @@ 2023-01-01T00:00:00+00:00 - 2023-01-01T00:00:00+00:00 + 2023-01-01T00:00:10+00:00 workspace-1 diff --git a/tools/src/test/resources/1.6/valid-license-expression-1.6.json b/tools/src/test/resources/1.6/valid-license-expression-1.6.json index 380554719..dd4f6b99a 100644 --- a/tools/src/test/resources/1.6/valid-license-expression-1.6.json +++ b/tools/src/test/resources/1.6/valid-license-expression-1.6.json @@ -6,18 +6,39 @@ "version": 1, "components": [ { - "type": "library", + "type": "application", "publisher": "Acme Inc", "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", + "description": "Modified version of Apache Catalina", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], "licenses": [ { "expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0", "acknowledgement": "declared", "bom-ref": "my-license" } - ] + ], + "purl": "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar" } ] } diff --git a/tools/src/test/resources/1.6/valid-license-expression-1.6.textproto b/tools/src/test/resources/1.6/valid-license-expression-1.6.textproto index a6c451a40..6666405fa 100644 --- a/tools/src/test/resources/1.6/valid-license-expression-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-license-expression-1.6.textproto @@ -5,14 +5,33 @@ spec_version: "1.6" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" components { - type: CLASSIFICATION_LIBRARY + type: CLASSIFICATION_APPLICATION publisher: "Acme Inc" group: "com.acme" name: "tomcat-catalina" version: "9.0.14" + description: "Modified version of Apache Catalina" + scope: SCOPE_REQUIRED + hashes { + alg: HASH_ALG_MD_5 + value: "3942447fac867ae5cdb3229b658f4d48" + } + hashes { + alg: HASH_ALG_SHA_1 + value: "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + } + hashes { + alg: HASH_ALG_SHA_256 + value: "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + } + hashes { + alg: HASH_ALG_SHA_512 + value: "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } licenses { expression: "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0" acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED bom_ref: "my-license" } + purl: "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar" } diff --git a/tools/src/test/resources/1.6/valid-license-expression-1.6.xml b/tools/src/test/resources/1.6/valid-license-expression-1.6.xml index 4eb0a6f73..77035ad79 100644 --- a/tools/src/test/resources/1.6/valid-license-expression-1.6.xml +++ b/tools/src/test/resources/1.6/valid-license-expression-1.6.xml @@ -15,9 +15,7 @@ e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 - - EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 - + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar diff --git a/tools/src/test/resources/1.6/valid-license-id-1.6.json b/tools/src/test/resources/1.6/valid-license-id-1.6.json index 76419c50d..f66e2dfcf 100644 --- a/tools/src/test/resources/1.6/valid-license-id-1.6.json +++ b/tools/src/test/resources/1.6/valid-license-id-1.6.json @@ -6,11 +6,31 @@ "version": 1, "components": [ { - "type": "library", + "type": "application", "publisher": "Acme Inc", "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", + "description": "Modified version of Apache Catalina", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], "licenses": [ { "license": { @@ -19,7 +39,8 @@ "bom-ref": "my-license" } } - ] + ], + "purl": "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar" } ] } diff --git a/tools/src/test/resources/1.6/valid-license-id-1.6.textproto b/tools/src/test/resources/1.6/valid-license-id-1.6.textproto index 228ff80b7..2b9009d7c 100644 --- a/tools/src/test/resources/1.6/valid-license-id-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-license-id-1.6.textproto @@ -5,15 +5,35 @@ spec_version: "1.6" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" components { - type: CLASSIFICATION_LIBRARY + type: CLASSIFICATION_APPLICATION publisher: "Acme Inc" group: "com.acme" name: "tomcat-catalina" version: "9.0.14" + description: "Modified version of Apache Catalina" + scope: SCOPE_REQUIRED + hashes { + alg: HASH_ALG_MD_5 + value: "3942447fac867ae5cdb3229b658f4d48" + } + hashes { + alg: HASH_ALG_SHA_1 + value: "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + } + hashes { + alg: HASH_ALG_SHA_256 + value: "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + } + hashes { + alg: HASH_ALG_SHA_512 + value: "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } licenses { license { id: "Apache-2.0" acknowledgement: LICENSE_ACKNOWLEDGEMENT_ENUMERATION_DECLARED + bom_ref: "my-license" } } + purl: "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar" } diff --git a/tools/src/test/resources/1.6/valid-license-name-1.6.json b/tools/src/test/resources/1.6/valid-license-name-1.6.json index 9de0228e9..1afc8250b 100644 --- a/tools/src/test/resources/1.6/valid-license-name-1.6.json +++ b/tools/src/test/resources/1.6/valid-license-name-1.6.json @@ -6,11 +6,31 @@ "version": 1, "components": [ { - "type": "library", + "type": "application", "publisher": "Acme Inc", "group": "com.acme", "name": "tomcat-catalina", "version": "9.0.14", + "description": "Modified version of Apache Catalina", + "scope": "required", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], "licenses": [ { "license": { @@ -18,7 +38,8 @@ "bom-ref": "my-license" } } - ] + ], + "purl": "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar" } ] } diff --git a/tools/src/test/resources/1.6/valid-license-name-1.6.textproto b/tools/src/test/resources/1.6/valid-license-name-1.6.textproto index 15033c48b..a157dbd00 100644 --- a/tools/src/test/resources/1.6/valid-license-name-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-license-name-1.6.textproto @@ -5,14 +5,34 @@ spec_version: "1.6" version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" components { - type: CLASSIFICATION_LIBRARY + type: CLASSIFICATION_APPLICATION publisher: "Acme Inc" group: "com.acme" name: "tomcat-catalina" version: "9.0.14" + description: "Modified version of Apache Catalina" + scope: SCOPE_REQUIRED + hashes { + alg: HASH_ALG_MD_5 + value: "3942447fac867ae5cdb3229b658f4d48" + } + hashes { + alg: HASH_ALG_SHA_1 + value: "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + } + hashes { + alg: HASH_ALG_SHA_256 + value: "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + } + hashes { + alg: HASH_ALG_SHA_512 + value: "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } licenses { license { name: "Apache License 2.0" + bom_ref: "my-license" } } + purl: "pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar" } diff --git a/tools/src/test/resources/1.6/valid-machine-learning-1.6.json b/tools/src/test/resources/1.6/valid-machine-learning-1.6.json index 491385e9f..fcd0264af 100644 --- a/tools/src/test/resources/1.6/valid-machine-learning-1.6.json +++ b/tools/src/test/resources/1.6/valid-machine-learning-1.6.json @@ -8,6 +8,7 @@ { "bom-ref": "component-a", "type": "machine-learning-model", + "publisher": "Acme Inc", "group": "CompVis", "name": "stable-diffusion", "version": "1.4", @@ -61,16 +62,20 @@ }, "considerations": { "users": [ - "Who are the intended users of the model?" + "Who are the intended users of the model?", + "Data scientists and ML researchers" ], "useCases": [ - "Who are the intended users of the model?" + "Who are the intended users of the model?", + "Text-to-image generation for creative applications" ], "technicalLimitations": [ - "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" + "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?", + "Limited performance on non-photographic styles" ], "performanceTradeoffs": [ - "What are the known tradeoffs in accuracy/performance of the model?" + "What are the known tradeoffs in accuracy/performance of the model?", + "Higher resolution output requires more computational resources" ], "ethicalConsiderations": [ { @@ -86,7 +91,17 @@ "mitigationStrategy": "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." } ] - } + }, + "properties": [ + { + "name": "modelcard:custom-property", + "value": "custom-value" + }, + { + "name": "modelcard:another-custom-property", + "value": "another-custom-value" + } + ] } } ] diff --git a/tools/src/test/resources/1.6/valid-machine-learning-1.6.textproto b/tools/src/test/resources/1.6/valid-machine-learning-1.6.textproto index c91c462cb..6ae5f0e93 100644 --- a/tools/src/test/resources/1.6/valid-machine-learning-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-machine-learning-1.6.textproto @@ -7,9 +7,11 @@ serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" components { type: CLASSIFICATION_MACHINE_LEARNING_MODEL bom_ref: "component-a" + publisher: "Acme Inc" group: "CompVis" name: "stable-diffusion" version: "1.4" + description: "Stable Diffusion is a latent text-to-image diffusion model capable of generating photo-realistic images given any text input. For more information about how Stable Diffusion functions, please have a look at \uD83E\uDD17's Stable Diffusion with \uD83E\uDDE8Diffusers blog." modelCard: { modelParameters: { approach: { @@ -32,7 +34,7 @@ components { format: "string" } outputs: { - format: "string" + format: "byte[]" } } quantitativeAnalysis: { @@ -45,12 +47,29 @@ components { upperBound: "The upper bound of the confidence interval" } } + graphics: { + description: "Performance images" + graphic: [ + { + name: "FID vs CLIP Scores on 512x512 samples for different v1-versions" + image: { + content_type: "image/jpeg" + encoding: "base64" + value: "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGBgYFBgYGBwkIBgcJBwYGCAsICQoKCgoKBggLDAsKDAkKCgr/2wBDAQICAgICAgUDAwUKBwYHCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgr/wAARCAH4AxgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAPDv2yv+CkH7G3/AAT/ALrwpYftYfFe68N3PjiW8i8K2tl4S1XV5dQe1WJrgKmnWs7LsWeI/OFyG4ztbGN+y9/wVb/YY/bK+Jp+D/7PHxO8Qav4gXTZb82mpfDPxDpMfkRlA7efqFhBDkF1+XfuOeAcHHyZ/wAFx/ird/BH/gpn+wN8U7D4UeLfHE2j+KfHUieFPAmnRXerahu0qyj2W8U0sSOw37yGkX5UY5JGD9i/smftw69+1R4r1Twvq37DPx4+FKaZp4uk1T4teE7HT7S9JkCeTA9tfXDNKM7iCqjaCc9qANj4f/t7fsnfFH4O/Ef4/eBPit9u8JfCTWNa0v4hat/YV/F/ZV3pMIm1CPypIFln8qMht0KSK/RC54rwnSf+DiL/AII+6xY22sJ+1feWenXao1vq+r/DHxLY2LK33W+03GnJCFOR8xcDnrXyt+wD/wAodv8Ago7/ANlg+NH/AKaEr7a/4IwWNlqf/BIL9njTdSs4ri2uPg3osdxbzxh0lRrNAysp4YEEgg8EGgD6G+F3xW+GPxu8B6d8Ufg58QtF8VeG9Xh83S9e8P6lFeWl0mSCUliZlbBBBweCCDgit+vzQ/4Je+GNH/ZN/wCC1X7Xn7C/wZtE0z4YXGjeHfH2h+FLQbLPQNSvLeNb1LeMfLCkzyBtigKqQxKoAQV9Zf8ABUXVP2qfDP7A/wATPHX7FPjt/D/xL8MeHX1zw5crpFrf/avsbLcT2fkXUUiOZ4I5oVwAweRSGBFAHvtFfB37Zv8AwVc1Sw/4I0eH/wBt39lSaMeP/jNpOiaJ8JdOjiiuHj8TauywJbqkqtHLLav9pYo6sjNaFWDAkHgv2/v2yv2sP2eP2i/gZ+w744/4KA+GvgRo+v8Awqk1Txd+0j4s8Eafdp4j8RWskVvLptulysenWLuC10xdAoWRFUL8quAfpdRXhH7BugftAaX4C1PWPjJ+3l4f/aD0nVLmKbwl4x0Pwhp+lGKEKwlikOnSvb3PzbSsiBMcgg9a8O/4ORPj78R/2dv+CPvxT8U/CjXZ9J1nWxpvh5dXtpSj2Vvf30NvcuGHKloHljDAgqZAQcgUAdj8TP8Aguz/AMEnfhN451P4d+KP2w9KvNT0SYxayfC/h/VNbtrBwSGWe6061ngiKkEMGcbSCDgg16F4w/4KZ/sI+CP2Qbn9vbVP2ktEvPhFZywRXXjTQIbjVIIpZbiO2SIxWUcswk86WNGTZuQt84UAkdh+yh+y58G/2Mv2fvDP7N/wI8IWWj+HfDOlxWsEdpbrG11IqASXUxUZkmlYF3kbLMzEkmvhf/g5o+Fvw2+FP/BC3426b8MvAek+H7bVfEug6nqNro1hHbRXF5Lr2nebcMkYCmR9oLNjLHJOSSSAfpbXnfgb9q74BfEn9ofx1+yn4K8e/bfH3w1s9NuvGug/2XdR/wBnQ38PnWjefJEsM3mR/NiJ3K9GCnivRK/PD9hr/lYa/bm/7E/4b/8ApnoA7zUf+Dhr/gkNpGo6pp2o/tS6jENF1SfTtWvT8LfE5s7S5hkMcqPdDTfJXawILb9vfOOa+svhR8Wvhj8dvh1pHxd+DXjzSvE/hjXrQXOj67ol6lxbXcRJG5HQkHDAqR1VlKkAgivx4/4Iz/8ABVf9ib9kL9lL4q/BL44ah4u1TxRJ8dfGV0nhDw18Lta1l9ShmugqQpLb2j2jPJtZdjzLjPzbQc19af8ABuV+zf8AG39mz/gnjcaX8b/hlf8AgWXxb8Sdd8UeGfAWqxmO58N6PdyR/ZrKSI8wsPLeTyyAyiYbgrblAB9c/tH/ALT37Pv7IXwtu/jV+0z8XNF8F+F7KVYpdX1u7EaPK2dsMajLzSsFYiOMM5CnAODXi3wH/wCC0/8AwTL/AGlfilo3wU+Ef7TsNz4q8RSFNA0bWfCmr6RLqTBSxFub+0hWY4BPyE5A4ry//gtj+yx+1P8AFXxd+z5+1l+y78F9M+K118BPiFc+INa+Eep6vFZf8JDBNBGizQSTgxC5tzGWj3AkNJuUOV2NF8Dv+C437PPxa/aC8Ifsr/tmfsffFL4CfEXxDqiJ4Hs/jB4NWPTtT1HIVI7C/BKvMWbYrlIwWdUVizhSAffNFfBPxj/aW/bl/bK/4KM+Pv8Agn3+wx8bdF+D/hv4J+HtHvvir8T7vwhBr2qXGparC1xZabY2t0fsyJ9nVneaQOQykADbhus+N3x4/ac/4JOf8E8/i9+1B+2D+0XY/HS88G2iXfhK+XwTb+HZ5ZJ3htLazu0tHaJgbuaPM0aoQjn5MqMgH2VRX5gfGnX/APgul+yR+xhP/wAFI/Hn7aXg7xrqPhnQIfFXjz9n5/hXY2OkQ6ZtWW8s7TVInN6JreEuRLIzhzEflPAboP8Agob/AMFC/wBsC68d/sQyf8E7/GOlaZaftJ3F7Nc2PirRYLq0msrjSbS6tbi5+UzKtqty9yY7eWJpTF5ZfDZAB+j9Ffmz+3B+19+2B/wS4+GXgv4M/Ev9vbwb43+JPx1+IZ0vwp8Sfin4S0zwx4f8BaVBbI+oXk6WsiJcLFuQxJNJuZ51VncKEfz3SP8AgqB8Sf2Rf2j/AIQaXr//AAWa+C/7XHgz4o/EKw8F+KPDnhqz8PWGu+F7i/LJbarapo9w5ls0mCpMJlYqrqAxZwVAP1oor8uvjt+3V+0d8Sv+ClvxW/ZD13/gqT4N/ZE0f4frpEfgLStf8D6TeXvjuK7tBNJqC3WtMIGjWUtEsVv8/wApDYZCW/Qb9mDw98Z/C3wQ0XRPj/8AHPS/iV4njE73PjjRvDselQatA8zvbSi1ikkjjbyGiVtjFWZSwwGwADv6K+P/APgrB+2p8f8A9n2/+Dv7LH7H9tokXxZ+P/jl/D/hrXvEtqbix8PWNvEJtQ1N4Aw+0PDEyFIidpLEndt2N5R46+Of/BRr/gl7+058ENI/az/a4034+fCf43fEG18AX2qXnw5sPDuq+FtfvEY2EkP2AiO4tpXSQOsilkVCdxOMgH6L0V+b/jP49/8ABTb49/8ABZH4y/sE/s7ftMaN4B+H/hf4deHdc/4SPUPA9lq11oEk8f7yOyidU8+e5kbJe6klihjgk2xFnXHoH/BN/wDaX/bB0r9tn42/8E2/21fi3pfxK1r4b6RoviTwf8SrDwxBo1xq+lagjh4ru0tv3EcsMqqoaMAMCxPYUAfbGrarYaHpVzreqz+Va2du89zLtLbI0UsxwAScAHgDNfFuif8ABxP/AMEifE2lw654c/aO8S6hZXAJt7yx+Cvi+WKUAkEq66SQ3II4PUV9h/EDSb7X/Aet6FpkQe5vdIuYLdCwUM7xMqjJ4HJHNflZ+zFr/wDwWR/4Inf8E4vCmifF39jb4U/ED4ZfCbQLm48XW/gf4jXf/CUWenG4mu7q88ue0W0l8hJXYxxyMSsR+YDLAA/TL43ftJ/Ar9m34OXn7QXx5+Jum+FPBthFBJea/rLtFDEJnVIgQRu3O7ooXG4lgMZrhf2KP+Ckv7FP/BRSx8S6p+xp8bY/Glt4QvILXxDPDoOoWSW0syyNEAby3i80MI3O6PcvHJGRntvh34x+CP7Y/wAAPC/xX0bSNO8UeCvGuiafr+ixa1psc0csEqJcW7vDKGCyLlTgjKOvYivi7/gkVaWtj/wU4/4KA2VjbRwwxfFPwykUMSBVRRpEgAAHAA9KAPpf9rP/AIKZ/sLfsN+JdM8EftQftC6b4b1/WbL7ZpXhyDT7vUdSurfe6CZLSyhmnMZaORQ+zBMbAHINbX7JH7eP7In7dvhnUfFn7J/xz0nxhb6NdLb61a2yTW17psrZ2rc2lykdxb7trbfMjXdsbGdpx6Nc+FfAmneJrj4oXfhzSYNZGlLZ3XiKSziW5FjG7yrC9wRv8lXkkcIW2guzYBJNfnP/AME8b/Sf20v+C1/xq/4KWfs3aCLP4L6b8MIPhpF4rt4fKtviF4gg1CO4uNTgwMXEVtHF9lFxyGCx7GILAAH6XVy/xr+M3w1/Z1+EfiP47fGPxJ/Y/hXwlo8+qeIdV+xzXH2S0hQvJJ5UCPJJhQTtRWY9ga/P79pz/gqN+0d/wSK/aK8eeB/217bXvix4E+IdrNq/7M2uaF4bt4r2XV8pGfBl0tjAil/MkjaC5dGdoixZpX+SP0jX/wBmb/gor+0B/wAEa/ij8GP2qPiHp/in44fFfwPrHk6FBZ2OnaZ4ZlvoSLbRYZII08yO3DKjTzPLIz7z5jrtoA6H4df8F4/+CXXxY8U6F4N8AfHXxNf33iXULWy0Qf8ACnPFkUNzNcOqQ/vpNLWJEZnX947KgByWAya9y/at/bO/Zc/Yd+HcHxX/AGsfjRpHgjQLq/FlaX+rM5+03JjeQQxJGrPI+yN22qpOFJr4XH7av/BSv/gkF+zv8Pb/APb6/ZL+Gur/AAQ8I6TofhbxL44+Efji9vNT8MQKkFjDf3lpeWkQuEaTywywHgyDBJwG/RzXvB3w7+JVppuoeJ/Cmja/BaTrfaRNqFhFdLBIUIWeEurbG2OQHXBwx5waAOD/AGOv23P2YP2/fhG/x2/ZI+Jw8W+FI9Xn0t9VGjXtji7hVGkj8u8hikOBIh3bdp3cE4OOE/aY/wCCvH/BOf8AZA+J1z8Ffj5+0zYab4vsreOfUPDGk6HqOsX9nE8ayI88GnW87who3RwXC5Vw3Qg14N/wbfgL+yx8Z1UYA/ap8c4A/wCvmGvuDxTd/Bj4GaP4q+Oni1fDvhazFp/afjTxVcww2okitoAgnu58AuI4Y1QM5O1EVRwAKAMj9mb9q39nP9sn4XwfGf8AZf8AjBovjTw1PO0H9p6NcFvJnUAtDNGwEkEoDKTHIquAykjBBPoNfnJ/wQp8Nav8Vfjx+1N/wUh8GfD+68H/AAm+P3jrSrj4V6Dd2RtW1G1022nt7jXvIIHlLfyy+cCQGYhycjYx+zf21PjF8Rf2ev2RPiX8dPhF8Pz4q8UeEfBGpatoHh4RO4vrqC3eSOMpH87ruUEonzMAQvJFAHp1FfmT/wAE6fjP+1h+2Na+AvjD4L/4L9/Dfx3qGof2fq/jX4M6Z8KtBj+y2zGOW80xRHMmpWrpGZIlnl3HcocpjIr1X/gq3+0ZrvwF8b6FJrH/AAWT8C/sweHbvQw0Oj3vw+0/Xdd1i7E0okuI1vHfZbKnlJ8lu3zh8uMgUAfcNFfnp/wRN/4KheKv2yvip8Yv2W/HH7R3hX40N8MG0q/8L/GLwl4cbR4/EumX0cm5bmy+5Bc280Rjby8I4cYHylm8p/4J3/ET/gtr/wAFK/2U/E3xi0L/AIKDeH/hxN4e8eeIdG8Jzn4T6Vqdx4ka1u3Ef21nRIbW1T5LZRBCZj5csryMSqUAfrDRX5YfsiftE/8ABYr/AIKufsEWf7a/wl/af8JfAm6stKu7XRvCumfDq11tPFep6fuiurm8nvmY2NvNdRSwpDApeJULmWQkIHftP/8ABXr9pnX/APg3P8K/8FQ/gTeW/hX4ja2+hx3iafptvcwm5/ttNOv4oYryOZFjlaOYJuVmRZBhiy7qAP1Nrz/x3+1J8Cfhn8fPAX7MHjfx19i8c/E631SfwPof9mXUn9pR6dAs94fOjiaGHy4mVsSuhbOE3Hivg39s34nf8Fkv+CdXwCH/AAUh+KH7WfhH4g6D4au7C9+KXwDsPhtZ2FhY6bc3EUNxHpeqLI15JLbGYBZJ3ZZApkKjHlN0n7YniXR/Gf8AwXJ/4J9eMPD1z51hq3hH4l3ljNtx5kMugWzo2O2VYGgD9DqK/LX48/8ABUjxv8ff25fip+zH4B/4KmfB79kvwR8GdRt9Fu/EPjQaJeeIPF+stHvuhbW+sTpDBZ25/dGQI7M4ODhsR7P7H3/BW347eJPhf+1V8JZfiL4A/aK+IX7Ovg//AISLwL4++GBhbTfiDZ3Gnz3FskkFjLLHHdRTwGGeKBsEuFQbhuYA/TGivy//AOCdPxy/a3/bV0fwJ8Y/Bv8AwX5+G3izW9USw1fxj8EtO+FOgoLGFtkt3pYVZk1OBo0MkQnkydyBymOK/UCgD59/au/4KnfsG/sSeP7D4UftIfHhdI8Ualpn9o2vhzSfDWp6zf8A2PeUFw8Gm21xJFGWVlDuFBKnBODXvtjeW+o2UOoWjlop4lkiZkKkqwyDggEcHoea/H/4C/sxftveIP8Agvj+0To2gf8ABTLXtI1jRvAvhS91TxAnws8P3Emq6XO8ksOlGKWAx28cKjYJogJZM7nJYZr3Hwt8dv8Agon/AMFNv2tfjh4I/ZI/ay034C/Cr4FeNpPAya1afDyw8Rat4o8Q26A35kF+TFbW0LsiqqLvcMDuBJ2gH6KUV+ef7N3/AAUO/ay139m79r/4G/tE6lokXx1/ZY0fUkm8ZeG9LSKy1qCbSLm+0fVhaS+YkUrrAXeAhowVHGGKCf8A4JK6l/wVU/bC/Z++DH7bX7Sn7b+maToes6Db3mo/DLQvhlprf8JFaeS8a3d7qDAPBPcPi52WkcMcSlI9rfMSAfoLWX448Z+Gvhx4L1j4h+M9S+xaPoOl3Go6teeS8nkW0EbSyybIwzttRWO1QWOMAE8VyP7Wn7Q/hv8AZJ/Zh+IH7Tvi3Tpb3T/AXhC/1y4sIHCvd/ZoHkWBWIIVpGVUBPALAmvzm8Rr/wAFqfij/wAEvPFP7ffj79rzwdfL4x+EWoeJrj9nmL4ZWsGmWug3enSTfZINWWT7aL1bOTzFeQyJ5wEbIy5egD7v1z/gop+xx4b/AGZPCP7Y+tfGHyfhv47vNNtfCniP/hH9Rb7dNfyeVaL9nW3M8XmOcZkjUL1YqOa1P2t/25P2U/2FPB+m+Ov2qvjBZ+FLHWtRFhosbWNze3Wo3O3cYre1tIpZ5iBydiNtyM4yM/nHpP7S3xp/ZV/4NyP2UfiL8CPF0Wi6xfan4E0a6u5tItL0PZXd4Ip4vLuopEBZCRvCh16qynmtD/grN8B/2p/G/wDwXM/Y2svh/wDtz6v4STxcfiA/gFYPAGj3y+BpLLw1atePCLmJhqBvOQftW/yN2YdpoA+1viD/AMFa/wDgn18KfgL4O/aV+I3x+Oj+FPiDc3EHgtr3wpqy6lq8kEjRzLDpn2X7cdjL8xMAADIejoT7L8FfjN8O/wBob4V6L8afhNq9zf8AhzxDafatJvLzSbqwlli3Fctb3ccc0Ryp+WRFPfGCK/J39s39lr9uiX/gtb+yh4Guf+CoOvy+I9Q8A+LX8M+MX+FHh7zPD0ltpNrHfyR2v2fyJzfMrO/mqfJ37YtqgCvV/wBsv/go18Xvh9+1n4W/4Jg6H/wUZ+GPwX1Hwp8LLDXviz+0R8VbPSIbrV759sMVrpunXUsNkLmfa11KMNHGkoCKNm1wD9NKK/OP/gnX/wAFJvHepf8ABQK+/wCCeXxK/bw+GP7Tek638P5fFfgb4t/DwaZDdW01vcLFdaRqdvpcslssgRhNHIgTKKcglgE47/gm/wDFD/gsD/wUh0D4l+Lb39vXTPht4X8BfHHxD4b0O/sfhVpOqapr0NrdAiCXzUSC3tYYmjhUrE1xI5mZ5RtQUAfqbRX5KTf8FU/H37afxz+KH/CJ/wDBZX4Jfsj+A/h746vvCfhTRfEUHh7UPEXimSyISfVbmPWblBb2bykiFYkDMqsGYFdzdR8Kv+CuXx5+LP8AwSn/AGsPHdl8XfBWrfFv9nK01rTrL4ofDhbW+0PxCIrM3Gna1bRv50H7xd2+E+ZGHibgBtigH6h1z/jv4s/Cv4Wz6Ha/E34l+H/DkvibXIdF8Nx69rMFm2ralMGMNlbCV1M9w4VtsSbnbacA4NfmP42+J/8AwW80D/gmLpv/AAVVb9uHwhY6honwtsfG+o/BU/Cmxl03VNNSzjuZlu9RyLpbuW33Tv8AZxDEkjGKNFUCSsP/AILTXvxi/ay8NfsB/tF/CT9ovUvAekfEX45eBZ9B0KHwxp9//YurajaT3dtrIluIy00tvG5jFs/+jvncyE4oA/XSivNP2VvhP8ffg58OLjwr+0b+1ZqPxh16XV5bmDxTqfhDTdFkhtWjiVLQQadHHEyqySP5hG8+aQThVx4F+3h+1V8fP2PP2/P2a/EF948x8Cfiprt38PvGuiTaXa7NP8R3UZl0a+W5MXnqZZFkgZDKIgqbthY5oA+yK+W/2kv+C1X/AAS9/ZH+Mb/s+fH79rbR9G8axXsFpc+G7TR9Q1G5tpplR4kmWyt5fJLLIjDeVGHB71znx0/aq+PfjP8A4LCfCP8AYK/Z28ef2R4c8O+BtT8ffHiSHS7W5N1pzMLTS9OEk8Tm3eS63SP5ZSUxEEMAMnyb/g5b8A+BNB/4Jwap4w0PwVpNlq+rfFjwe2q6paabFHc3rLqluoMsqqGkIVVUbicBQOwoA/SCiqHijxV4Y8EeH7rxZ408R2GkaVYxebfanql4lvb26dNzySEKg5HJIFfLn/BRP9pjx94p/YH+KfxH/wCCZX7Tvha9+JXgDQV8RWv/AAjl1pmuCW3tXE9xaSwMJgPPtoriNCAr79u1gQaAPrKivhH9u3/gqZrmmf8ABIrwr+1x+xzexr8QvjrD4f0H4M2jQw3Lx+INZZESIpKrRvLbL9pYo6Mpe22spBIrk/8Agob/AMFFfi7+zh8bfg7/AME1tC/bT+G3wv8AGfiH4eDxF8TP2hPizHp0FtZWUB+yCSzspnt7Sa+vLuKdhEdscaI5WMjlAD9GqK/Mn9j3/gpf4+8Cf8FFfAX7DXjn/gpb8Kv2sPC/xf0LV5vDXjbwNHo1tq/hfVtNt/tT2moQaPM9ubae3EhikKo7SRsvIQ5pfsv/ABa/4K3/ALfP7Tv7Unwf8Eftv6Z8L/A/wl+OGpaF4a8UQ/DHS9Y1V4gAIdMijnRIFggRfMeaZZp5WuUUOoQkgH6h15/+1H+1H8Cf2LvgTrv7S/7S/jn/AIRrwT4a+y/23rf9mXV59m+0XUVrD+5tYpZn3TTxJ8qHG7JwoJH54fFv9t/9qDx5/wAFFPiX+xt42/4KveDf2UrL4cWmiW/g2DxB4A0e4vviH9psVmn1RZ9YYW4j8/fGsFr8wwVJBQlvTP8Agqx8dP20P2Fv+CEvj744W/7UGjeLfiv4ZGkPY/E3TfA1hDa38F14ksoEl/s6YXNqGNlceW3DqWzIm07doB+gdFfFX/BSH9r39qWw/aw+Dn/BNf8AYd8SaJ4V8efFi01TWvEXxG1/RV1KPwnoNggLzwWbsqXNzLJujQSEoCmGHz74+R8E/tE/t5/sHf8ABRT4U/sZftpftF6Z8bPAfx80/V4fBHj5vBFnoGq6FrenW4uJLO5hscQTW8sTKEcIr73A4CMWAP0Dor8y/hL8ZP8Agqz+2n/wUC/ar/Zg+FX7Y2lfDPwB8J/Gul22ieKG+HOm6xqlqLiwEi6daxTIkJj3LJNLPc+fJzEkYQFmHXfsc/t8/tq6b8Fv2uPhD8erHTPin8Yv2WLi+XRtV0DQ/wCz18bwvpUl/pnmWcBIhuJTGUdIePnVVBYFmAP0Gor8tf8AgnT8fv2vf24vDfgf4yeEP+C+3w11zxNrENlq3i34Gaf8J9CA0xW2S3Wk7POTU4mjXzIhcOSSyb9pHB/UqgAooooAKKKKACiiigAooooAKKKKAPjP9v39lH4+/Gz/AIKU/sZfH/4Y+Av7T8I/CfxJ4uuvH+rf2paw/wBlQ3umW8Fs3lSyrLPvkRlxCjlcZYKCDX2ZRRQB+b/7IH7BP7WPwu/4JsftrfAHx38KfsPi34t/Ej4nap8PdJ/t2wl/tW01bTlh0+TzY52ig82QFdszxsnVwg5qp+xB8Vv+Cx/7LH7Fnw1/ZOsf+CMNxda14F8E2Gg/8JHr3x/8N2+nTSwQrH9oZLWS4nCZG7YqliOMjqP0rooA+Qf+CYf/AAT++Mv7N3jv4r/tiftj/EHQ/E/xz+OesWl54xm8LRSrpGh2FnEYbHSrEzASPHFGdpkcAvtjBBMe9/r10SRSjqGVhggjIIpaKAPyK/Y8/wCCSP7avw3/AOCiPhb4NfFbwFaQfsm/s/8AxM8WfEL4LamuvWco1G81QQNp2nNaJM1xF/Z8s97MkjxIpcS8kMm77W/bq8b/ALYWm+K4PAvw4/4JkeF/2iPhnqehRPqltqHj/S9Nu7XUhNOHje01WM29xAYvIKuJFYM0gIIxXb+P/j1+0X/w0XrPwF+BHwL8Fa+nh/wVouv6nq/i74k3ejEnUbvVbeOCKG30e+3hP7KdmdnTPnKAvykl3/Ccf8FC/wDo1/4M/wDh+NW/+ZegD5w/4I2/sH/HX9lz4w/Hv9oH4ifArwx8EvC3xc1rR7nwj8A/B/iCPUrPwybO2khuLt5LdEtUmumZXKW42KFAJIVAPpv9uv8AY9+HH7fX7JPjj9kT4rXM9to3jXSPsrX9qgaWxuY5EntrpFPDNFPFFKFPDbMHgmqf/Ccf8FC/+jX/AIM/+H41b/5l6P8AhOP+Chf/AEa/8Gf/AA/Grf8AzL0AfNPwb+NH/Bcb9ln4caZ+z/8AFH/gnT4f+PN/4ZsY9O034reDPjPpmiQa5bxKEhnvbPU0We3uCiqZWjEqs5YquMZwf+Co/wCzH/wU0/b2/wCCKfxH+B3jb4N+Dbj4y+LfEWmXeieA/A/iWP7JYadBq9jOtu99qDQRy3CQwyvJJlUZsiMY2ivrT/hOP+Chf/Rr/wAGf/D8at/8y9H/AAnH/BQv/o1/4M/+H41b/wCZegDwW1/b8/4LEy3McVz/AMECNbijaQCSU/tLeE22KTy2A+TjritT9lP9lH4+/Db/AILKftW/tWeNfAX2LwD8SvDfgm18Fa9/alrJ/aM1hpvk3a+RHK00PlyfLmVEDdVLDmvZv+E4/wCChf8A0a/8Gf8Aw/Grf/MvR/wnH/BQv/o1/wCDP/h+NW/+ZegDxn/gh3+yj8ff2Pv2W/Gvw5/aL8Bf8I7rOr/GzxPr+n2f9qWt35unXdwj282+1lkRd6gnYxDr/Eor7Mrxn/hOP+Chf/Rr/wAGf/D8at/8y9H/AAnH/BQv/o1/4M/+H41b/wCZegCt+2T8Sf27/ha3hjxL+xj+zR4S+KtiJbtPGnhnW/G39g6iVIh+zSWNzLG9ucHz/MSUDP7vaw+avj39pL4Cf8FLP+CtXxa+DHgz4/8A7EOjfs/fDT4V/FnTPHuu69rXxM0/xBrerzWAkEdjYxaaGS3WTzWDySOP4WAzHsk+y/8AhOP+Chf/AEa/8Gf/AA/Grf8AzL0f8Jx/wUL/AOjX/gz/AOH41b/5l6APm74x/s1/tzfsZ/8ABRrx9/wUD/YZ+B+jfGHw18bfD2j2PxU+GN14wt9B1S21PSoWtrLUrG6ux9meP7OzI8MjIxZiQTuyvW/HD4DftN/8FY/+Cefxd/Zf/bA/Z1sfgXeeMrRLTwlYr42t/EU8UkDw3dteXb2iLEoF3DHmKNnJRD8+WGPZP+E4/wCChf8A0a/8Gf8Aw/Grf/MvR/wnH/BQv/o1/wCDP/h+NW/+ZegD4n+NWg/8F0f2uP2MLj/gm747/Yq8H+CtR8TeH4fCvjz9oCT4q2N/o82m7VivL200uJBema4hDgRSKgQyn5hwV9V/aD/YA+KOk/tO/sFQ/ADwRLqnw+/Z1m1fTvE2rT6pawvpmnDQIdPsnaOWRJJy7RBSIUcg8kAc19B/8Jx/wUL/AOjX/gz/AOH41b/5l6P+E4/4KF/9Gv8AwZ/8Pxq3/wAy9AHkP/BXH/gn58Qf2wrH4WfHP4EaP4O1n4i/BHxfLrfh/wAK/EK283RPEtlcQiG+0u5Ox/KMsaRmOUqwR4xkDdvThfgjoX7UXiz4s+FtO1//AIN8/hF8LNPg1y1l1/xxqvj7w3fnTrdJVaSaxg060aeacAZiL+SAwBbGK+mP+E4/4KF/9Gv/AAZ/8Pxq3/zL0f8ACcf8FC/+jX/gz/4fjVv/AJl6APBP2zNa/bM+IXjPxF8KPHf/AAQ78BftB+Borp18Ia/qHxO0GGOa3dF/4+bTVoC9rIGyC8JkzgEAEV1//BFf9iz41/sFfsMad8B/jxrGmnWH8T6rrFr4c0PUZryw8L2d3cGWHSbaeYBpY4QSS2Mb5HwWADt6Z/wnH/BQv/o1/wCDP/h+NW/+Zej/AITj/goX/wBGv/Bn/wAPxq3/AMy9AHkv/BV/9iz4/ftBah8Hf2qP2QLjRJfix8APHL+IPDWg+JLs29j4hsbiIQ6hpjzhT9neaJUCSkFVKkHbu3r5R47+Bv8AwUZ/4Kh/tN/BDVv2sv2RtN+Afwn+CPxBtfH99pd58RrDxFqvinX7NWFhFD/Z4MdvbRO8hdpGDOrkBQcY+sf+E4/4KF/9Gv8AwZ/8Pxq3/wAy9H/Ccf8ABQv/AKNf+DP/AIfjVv8A5l6APJfgB+y38dvBP/BZn9oL9q/xP4F+y+APHHw38KaX4X1/+07V/tt3ZpILmPyElM8ewsPmkRVbPyk0fBn9lv47eFP+C1fxo/a31/wL9n+Hviz4P+HNE8P+IP7TtX+1X9rM7Tw+QspnTaCDueNVPYmvWv8AhOP+Chf/AEa/8Gf/AA/Grf8AzL0f8Jx/wUL/AOjX/gz/AOH41b/5l6APSfijqHxB0n4Z+ItV+Evh6w1fxXbaFdy+GdJ1S8Nva3uoLC5toJpQCYo3lCKzgHarE9q+Cf2mfin/AMFuP2w/gF4n/ZN8Kf8ABLbw78KLvx/oV14f1r4k+KvjnpWr6Zo9ldxNBczw21jH9qnk8p32ZjXaxUkNjbX1b/wnH/BQv/o1/wCDP/h+NW/+Zej/AITj/goX/wBGv/Bn/wAPxq3/AMy9AGT4J+F3xA/4J6f8E8vC/wAFv2YPg/efF/xB8MvBmlaLofhgeILTRZvEDw+TBNMbm7byLYlTLcEMcfKUXkrXw7+wcP8AgsH+zz+2x8dfjr44/wCCOOpJov7QHj/RNTuZF+PPhdj4Xtre3NrK7hJ2a7wrmXCKjELtAJINffH/AAnH/BQv/o1/4M/+H41b/wCZej/hOP8AgoX/ANGv/Bn/AMPxq3/zL0AfJX/BcXwD/wAFSP2kvF/hH9lf9mP9lnXvFfwB1SwjvvjNqvg34j6LoeseIB50ynw/HJqF1E9tbskcTzTIj+alx5YICSK/u/7AfxK/aZtG039njxj/AMEmb/8AZ8+HfhjwwYvDt+PiX4e1a0iaJ4kisUttNneVSyNI/msNuY23Hc4z33/Ccf8ABQv/AKNf+DP/AIfjVv8A5l6P+E4/4KF/9Gv/AAZ/8Pxq3/zL0AfHPxR/4JRfGP8A4K1fGz4mfGv/AIKU6NrHw/0PRbK58M/s0+CtK8SW8934WXdHKfFk0ljPJCb+aaOIpF5hEccZjcNhGr3b9nL4g/8ABVrwX+wXqOm/Gv8AZn0TxR8efAeox6RpwufG1laaX8RrKG6iT+1ormFpWsJJrQyuUuIkYTpkxqr7V9Q/4Tj/AIKF/wDRr/wZ/wDD8at/8y9H/Ccf8FC/+jX/AIM/+H41b/5l6APjP9tXwR/wV0/4K0/BWb9hXxl+wVo/7PPgLxfqNiPiN8QvEfxY0zxDdLptvdxXLwadaacCWmdoUAebYuMqQu7ev2p+0x4/+P37N/wS0ib9kT9kG7+Mmr2d7a6Yng+18c6foL21gsEgN0brUCI3CGOJPLHzt5u4cK1V/wDhOP8AgoX/ANGv/Bn/AMPxq3/zL0f8Jx/wUL/6Nf8Agz/4fjVv/mXoA+JP+CLHh7/gqj+yHNrXwA+P3/BLG/0Pwz4++Mmv+LtV+IA+M3h26j0C31FhKsTWVtPJNclGjVCUwTvztABqn/wVh+EX/BUH9rj9tbS/hXqf/BPzW/iV+yd4Kaz1I+GfC/xV8P6MfiJqwihnX+0/tt3HMljbTM8YtfLAleDzCzB49n3P/wAJx/wUL/6Nf+DP/h+NW/8AmXo/4Tj/AIKF/wDRr/wZ/wDD8at/8y9AFP8AYw+NX7UHxRtNW8P/ALQP/BPbUfgPp+g2lnD4ahu/HuiazFqKESK8USaXK4tlhWOIYcKCJQF+6cekfG/WPi94f+E2va38A/Bmk+IvGNrYNL4f0LXNUaytL+4BBEMk6qxhDDI37SAcEgiuD/4Tj/goX/0a/wDBn/w/Grf/ADL0f8Jx/wAFC/8Ao1/4M/8Ah+NW/wDmXoA/Pz9qn9i79tn/AIKL+P8AwHLF/wAEhvA37N/jLQfiJpXiHVf2hB8TNF1DVLCC1nEs0dp/ZUS3V3JKMhRceXHkDcFJDp6x8e/2av22v2dP+CtXij/gof8AAb9jPQv2g9B8ffDrS/D0OnzeN9P0TWPBVxZsd5t31EeU1tPkO4jYOXJJA2DzPqv/AITj/goX/wBGv/Bn/wAPxq3/AMy9H/Ccf8FC/wDo1/4M/wDh+NW/+ZegD5f/AOCbn7Ln/BQfwr/wVI/aC/bU/bV+GehaDYfFLwX4ch8PReG/EUF/aacbUOn9mBtyzyyQRCPzZ3hijkleQx5TBr0b/gh/+y38dv2QP2IpvhB+0V4F/wCEd8RN8SPE2qLp39p2t3m0u9Slmt5PMtZZI/njZW27ty5wwB4r1r/hOP8AgoX/ANGv/Bn/AMPxq3/zL0f8Jx/wUL/6Nf8Agz/4fjVv/mXoA8Z/4Iifso/H39kL/glV4V/Zt/aJ8Bf8I9410288SPe6L/alrd+Wt1q99cQHzraWSI7opo24c43YbBBA+DP2u/2VPjz+yl/waUeFf2Vv2gfDLeEfHeh+KNKttWsF1C2vTYSXHjJp4XEtrLJFJ+7mif5JDjOCQQQP1Z/4Tj/goX/0a/8ABn/w/Grf/MvXn/7TXwU/aV/bG+E1x8Df2jv2Jfgz4j8LXeoWd9caX/w0X4gs989rOlxA/mWvhuOQbZY0bAbBxgggkUAfOf7Z3wz/AOCyX/BRb4A/8O3vid+yV4S+HuheJruwsvij8fLH4lWd/YXum21xFNcS6XpaxreRy3JhBWOdFWMOYyxz5q+x/tE/sbfF/Wf+Cpv7G/xv+FHw88/4bfBvwx430zxVq39q2yf2St5o8Fpp6eTJKs0+94ymYkfbjL7RzXtP/Ccf8FC/+jX/AIM/+H41b/5l6P8AhOP+Chf/AEa/8Gf/AA/Grf8AzL0AfG3xN/YB/aB/ZI/bW+K/7RnwK/4J9fDf9pzwB8a9ag8Qan4X8Q6rpemeIPCmtCIR3T29xqkTW9zaTkCTZvR1c4AAXMnuv7MNn+1x4d+GHxK+Iejf8EtPhN8FfFi6Vbr8P/CGm+MbGefX7hBM0iald6daJDbR7vJEewzYLSM3QA+qf8Jx/wAFC/8Ao1/4M/8Ah+NW/wDmXo/4Tj/goX/0a/8ABn/w/Grf/MvQB+fH7YX7GP7cH/BSXX/CWmL/AMEgPAv7O3jnTPHel65fftFn4naLqGpaRHa3KzTfYzpcS3l1JIAQon8tM4LBTh0/W2vGf+E4/wCChf8A0a/8Gf8Aw/Grf/MvR/wnH/BQv/o1/wCDP/h+NW/+ZegDyX4Afst/HbwT/wAFmf2gv2r/ABP4F+y+APHHw38KaX4X1/8AtO1f7bd2aSC5j8hJTPHsLD5pEVWz8pNeV+FvgV/wUT/4Jk/tafHDxt+yT+yZpvx7+FXx18bSeOY9GtPiJYeHdW8L+IbhAL8SnUAIrm2mdUZWjbegUDaSDu+rv+E4/wCChf8A0a/8Gf8Aw/Grf/MvR/wnH/BQv/o1/wCDP/h+NW/+ZegD5Z/Zu/4J4/tY6F+zf+1/8c/2iNL0ST46ftT6PqTy+DfDeqJLZaLBDpFzY6PpIu5fLSWVFnKPOSsZLDnClz9Kf8Evfgz8Sv2df+CdfwV+BPxj8N/2P4q8JfDfStL8Q6V9shuPsl3DbokkfmwO8cmGBG5GZT2JrS/4Tj/goX/0a/8ABn/w/Grf/MvR/wAJx/wUL/6Nf+DP/h+NW/8AmXoA6P8Aa1/Z48Oftb/swfED9mHxZqUllp/j3whf6HcX8MYd7T7TA8azqpIDNGzK4BOCVANfn3pXhD/gubbf8E8NR/4Jg3n7Fvg9dW0z4bXHgey+PUPxTsX0zUdLjsmtI7iDTCq3YvZLYLEqzeVEJmEryIuVH3D/AMJx/wAFC/8Ao1/4M/8Ah+NW/wDmXo/4Tj/goX/0a/8ABn/w/Grf/MvQB8RfFT/gnX+2P4k/4IW/s6fscaL8HvO+JHgTxJ4KuvFfhz/hINOX7DDYXolu2+0NcCCXy0GcRyMW6KGPFfQn7Zf7Lnx2+K//AAVi/Yv/AGl/AHgb7f4J+E3/AAsX/hYGt/2naxf2V/amhQWtj+5klWafzZkZP3KSbMZfauDXrP8AwnH/AAUL/wCjX/gz/wCH41b/AOZej/hOP+Chf/Rr/wAGf/D8at/8y9AHkv7TP7Lfx2+IP/BYf9mP9qfwh4F+1+A/h54P8aWPjDXf7TtY/wCz57+zijtE8h5RNLvdWGY0cLjLFRzXnP7dH/BP742+G/2+h/wUg/Zs/ZX+Hnx4i8ReBYPC3xF+EXj27tLK4lNtN5lrqmmXl5FJBHOqHyZI5dqsijBJbKfUH/Ccf8FC/wDo1/4M/wDh+NW/+Zej/hOP+Chf/Rr/AMGf/D8at/8AMvQB5T+wtoHx11P403Pij4k/8Eg/hr+zvoNn4fnWz1yw8VaNqevXl88sIWFV0q3EcNv5Xnl2M7MWEYC4yaj/AOCLn7Lfx2/ZM/Z6+Ifgb9oHwL/YGqa78ePFniLSrX+07W78/Tb27WS2n3W0sirvUE7GIdf4lBr1r/hOP+Chf/Rr/wAGf/D8at/8y9H/AAnH/BQv/o1/4M/+H41b/wCZegD4b8N/sBftIf8ABPj4wfErRPhV/wAEvPhj+1F8MvH/AI+1Dxd4Y1C91zRdJ8ReFpb5lkn0y4OrRGO6tUkBMLxybwrNuBJ2r618R/2dv2nPjr/wSp/aF+Elv/wT7+H/AMHfHXj7wlqul+EPh34G8SadcPfh7ERwG9vI4bW1WdpnlUDcURNuZOTX0V/wnH/BQv8A6Nf+DP8A4fjVv/mXo/4Tj/goX/0a/wDBn/w/Grf/ADL0AeY/F79mX43+KP8Agh5rP7H2heCfP+It1+zGfCdv4d/tK2XdrH9gi0+zfaGkEA/f/J5hk8vvu28147+1P+wb+134o/4JvfsdaR8I/hlp2sfFD9mnxR8PfFmsfD7UfEdvZjVpNH0z7NeabHe5e3SXe5CyljHiNiC2Vz9Yf8Jx/wAFC/8Ao1/4M/8Ah+NW/wDmXo/4Tj/goX/0a/8ABn/w/Grf/MvQBufsr/Fj4+fGP4cXHir9o39lPUfg9r0WrS20PhbU/F2m61JNbLHGy3QuNOkeIKzPIgQkOPKJIAZc+df8Fav2NtU/bv8A2APiF+z94O/d+LptMXVvAF2s6wvba/YyLdWLJKxAh3TRLE0mRtSV+2a6n/hOP+Chf/Rr/wAGf/D8at/8y9H/AAnH/BQv/o1/4M/+H41b/wCZegD5+/4Ix/sr/tf+B9W+Mf7bP/BRfwBZ+HPjb8Z/FVmuo6LZ6raX0el6HplnHbWFuktrLLENxM8jBG5zGWAYEDzP/gvD4O/4KcfthfDvV/2N/wBmT/gmje+KvDFr4q8Pa3pvxPHxc8P2MV/9klgu5oRYXc0c8REgeDcxwSm8AqRX2b/wnH/BQv8A6Nf+DP8A4fjVv/mXo/4Tj/goX/0a/wDBn/w/Grf/ADL0AZv7PXir41ftjfB7xP4T/b//AOCd9n8NrK6uhYt4H8V+LtH8W2mvWRRXaSUWgeEJv+XypASSucYxXZfBT9jz9kj9muTVJv2c/wBlr4c+AH1yGOHWn8FeCLDSjqEabtiTm1hTzVXe+A2QN7Y6muf/AOE4/wCChf8A0a/8Gf8Aw/Grf/MvR/wnH/BQv/o1/wCDP/h+NW/+ZegD88v2GP8Agkr+2z8Lv+CgnhL4TfG3wLaw/ss/s3+NvGHi/wCA+pjX7Oc6pcatJCbCzltUmaeM2PnXkqyyRoPMDYyGXP0J/wAFK/8Agn58X/Gv7YfgH/go9+zb8DPAPxa8ReFfBl14O8Z/CX4jSwQW/iHRJLk3UL2V1cRSw2t7BcPIwaVdrJIRuXBD/RP/AAnH/BQv/o1/4M/+H41b/wCZej/hOP8AgoX/ANGv/Bn/AMPxq3/zL0AeJfsd6F+0Hr3x80jW/G3/AARP+GHwC0HTba5lu/GB8YaDqWsiZoWSOOzi0m2IQMzEPI8y/u2YBcnFaf8AwSy/Zb+O37OPxY/ar8TfGfwL/Y1j8Sf2kNX8U+Cp/wC07W4/tHSZoLdIrnEErmHcyMPLlCSDHKjIr1r/AITj/goX/wBGv/Bn/wAPxq3/AMy9H/Ccf8FC/wDo1/4M/wDh+NW/+ZegDwT9szWv2zPiF4z8RfCjx3/wQ78BftB+Borp18Ia/qHxO0GGOa3dF/4+bTVoC9rIGyC8JkzgEAEV83/EL/gkT+3D4b/4Nt/iL/wTw0Dw7pviX4neKPE9vrHhrwFofiWMWGgWb+JbDUP7JtrzUJIkaO3ghmkLOyguzqpclS/6F/8ACcf8FC/+jX/gz/4fjVv/AJl66T9l/wCMvif48fCT/hPPGngew8OavbeKPEGhanpGl64+pW0U+laze6W7xXMlvbNKkjWZkG6GMgSbSDjJAPmz/gpB+yF+1LfftYfBv/gpT+w94a0XxV48+E9pqmi+Ivhzr+tLpkfizQb9AHggvHVktrmKTdIhkAQl8sfk2Scj4J/Z2/by/bx/4KKfCn9s39tH9nPTfgl4E+Aen6vN4J8At43s9f1bXtb1GBbeS8uZrHMENvFEqlEDs+9AeQ7Bf0DooA+P/wDgnn+y38dvgZ+27+198X/in4F/svw78UfiRo+qeBdR/tO1n/tO0g03yZZPLhleSHbJ8u2VUY9QCOa5z9mf9m39sX9n39rf9uX9ojQPg/plxN8StY0DUvg9HrXiK3jtPEM1lozwOkzQPJLZp5+2MtLGpwdyqwGa+46KAPyP/bZ/Y0/bo/4KYroXhX/hz14E/Z98fweMdM1af9pBvihouoajoK210k8stk2mwre3UjqhVVmEaZYE4IDr+uFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRX5wf8Fev2Rv2N/ht8MdZ8TfCH4TXMv7U3xb8RSwfBbXND1y7Pid/EssomF1b3LTGS0sLQHz5wClrFBGUKgMikA/R+ivib/gpD+zT+z5P4NtvjT8aP8AgmL4i/aU8ey+GPsF5f8AgyK1+0ae1vDkSRm4vYZbQPI7lXsYpZwQTsJC59R/4JLatrOt/wDBNb4L6l4i+O8XxMv38CWi3vjaKWd/7RlUFWDNcok7PEQYWaZElLQsZFV9wAB0Xgf/AJSF/FD/ALIz4D/9O3i+vZq+ePgF8TvDfxR/b9+L+oeGtN8Q20enfCvwPY3C+IvCOo6O7ypqvi4lokv4IWni+YYmjDRMchXJU4+h6ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAor5w/bY/bY8Vfs2eKtJ8D+B/Cmn3l7eaeL66utVWRoliMjxqiLG6HdmNiSTgDHBzx6/8A/itH8b/AIQ6J8UY9JaxOq27tLaM27y5EkeJwD3XchIPoRXzeB4tyLMeIMRktCo3iKCvNcrS6XtLZtc0b22ut9bfRY3hXO8vyHD5zXppYeu7QfMm+trx3V+WVu9ntpfsKKKK+kPnQooooAKKKKACiiigAooooAK8Z/YP/wCSIa5/2Wb4j/8Aqa63Xs1eM/sH/wDJENc/7LN8R/8A1NdboA9mooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr4lm/wCCbn7cWjfto+Pf20vBX7fXgGfXfFYOneHF8a/AO41abwloCuXi0eylj8QW0aRZw8siwo9xKN8mcKq/bVFAHz98WvgN/wAFBvFniSa8+E3/AAUD8PeEtIvdMt4LrTrr4KQalPZ3Kwqk1xZTtqEYi8yQNKEuI7kIW25ZQBXc/sh/sv8AgD9jD9m/wp+zJ8ML/UrzR/Cti8MV/rFwJbu9mlmkuLi5mZVVTJLPLLK21VUFyAAABXpFFAHjPgf/AJSF/FD/ALIz4D/9O3i+vZq8Z8D/APKQv4of9kZ8B/8Ap28X17NQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFc58Vvi38N/gd4FvfiX8WPF1roeh6eoN1f3ZOAScKqqoLOxPAVQWPYGrhTnVmoQTbeiS1bfkiKlSnSg5zaSWrb0SXds6OiuJ+BH7RvwT/aa8IP47+BnxAtfEGmRXBgnmgikikhkAztkilVJIzggjcoyORkV21OrSq0Kjp1YuMlumrNeqYqNajiKSqUpKUXqmmmn6NaBRRRWZofP37XHw+8G/FD48fCHwH4v0GK8t9SvtWN2hZkeSCG2SUpvQhgu7BwDXu2haFo3hjRrbw94e0yGzsbOFYrW1t4wqRIBgKAK8j+I3/Ez/AG3PhxY9f7L8M6xeY9PMVYc/pXs9fI8PYbDPO81xigueVZQ5rLmahRpaXte3NJu199dz6vP8TiFk2WYRzfJGi58t3ZOdarra9r8qSvbbTYKKKK+uPlAooooAKKKKACiiigAooooAK8Z/YP8A+SIa5/2Wb4j/APqa63Xs1eM/sH/8kQ1z/ss3xH/9TXW6APZqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDxnwP8A8pC/ih/2RnwH/wCnbxfXs1eM+B/+UhfxQ/7Iz4D/APTt4vr2agAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK+cf+Cp/j74+fDf9ky+8R/s+S39vqA1WCPWtR0tT9psdOKSmSaNl+ZCJBCpccqrscjGR5j/AMEVP2gvjb8avAHjXQ/i/wCO7vxBFoF/Zf2Re6tfG4vR56zGVJHcmRkHlxlS2eWcA4GB49TOaNPOYZc4S5pR5lL7Ozdu/Tfo9DwKvEGHo8QwymVOXPOPMpacuzdu70Tu1onZH25RRRXsHvhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAV8m/8Fq/h1ofjv8AYN1zWda16WxfwtrFjq1gsabhdXBc2iwMPRhdN06MFPQGvrKvl/8A4KR/8V/rvwV/Zph+f/hN/irZ3OqQdfN0zTlNzdLj8YzntivZ4flOnnVCpF25JczflFSlL8E18zxOI4wqZHXpSV+ePKl5ycYx/wDJmn8il/wSo/YF8WfsP/DvxBd/EPxXa3+v+MJbOa9stOLm3sY4Fl8tAzqrNITO+87QOFAzjJ+raKK48wx+JzTGTxWId5y30t5Ky8krHbluXYXKsDDCYdWhBWV3d922+7bbCiiiuI7jxc/8TT/goEB1TS/hTn6SSah/8TXtFeMfDz/iZ/tu/EW+6/2X4X0izz6eYGmx+lez18xwt79HF1f58TXf3TjD/wBsPpeJ/drYSl/LhqC++Mp/+3hRRRX0580FFFFABRRRQAUUUUAFFFFABXjP7B//ACRDXP8Ass3xH/8AU11uvZq8Z/YP/wCSIa5/2Wb4j/8Aqa63QB7NRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXzv4x/4Kt/sC/D74iah8MvGnx5Om3mka+dE1jV7rwrqq6Lp2oiXyTa3GrfZfsFvIJDsKyTrhuDzX0RXxV/wU68e3/wC1pa61/wAEhP2bLK11Txj8QtCWP4p6/JAJbD4d+GLlsTX112a/uE8xLO1yHdz57FI49zAHrvx3/wCCmH7Fn7Nfj7Ufhn8X/ivfWWr6JaRXWvx6Z4M1jU4NHgkj8xJb24srSaGyQoQ+6d0G05zjmvaPCfizwv488Lab448EeIrLV9G1iwivdJ1XTbpZ7e8tpUDxzRSISro6MGVgSCCCK+dP21v2nZP2b/BWgfsifs0+EofGnxq8faQ+mfDvwdeSeZFBbxxLBLrerPg+Tp1su1pZGGZmCwxhnf5fSP2IP2Y9O/Yv/ZD+HP7Kml+JZtZj8B+ErPSH1adNrXksUYEkoXJ2KzliqZO1SFycZoAzPA//ACkL+KH/AGRnwH/6dvF9ezV88fALUvivqf7fvxfk+LPgvw9olzH8K/A6aZF4d8Tz6olxZjVfF2yaV5rK0MMpO4GJVkVQARI2SB9D0AFFFeR/teftrfBH9ifwbY+MPjFdahK2q3LQaVpOjWyTXd4yAGQoruiBUDLuZmAG5RySBW+Gw2IxleNGhFynLZLdmGJxWHwVCVevNRhHVt6JHrlFcD+zV+0r8K/2sfhXa/F/4QapPPpk87288F5CI7izuEALwSoCQrgMp4JBDKQSCDXfVNajVw9WVKrFxlF2ae6fYqhXo4mjGrSkpRkrprVNPqgooorI1CiiigAooooAKKKKACiiigAooooAKKKKACiiigAr5i/bB8L+IP2cPinp37fnws0ma5i0+BNN+K2iWi86noxIAuwvea3ODn+4oyQqNn6dqK/sLHVbGfS9Ts4ri2uYWiuLeZAySowIZWB4IIJBB6g1yY3CrF0ORO0lrF/yyWz/AEa6ptdThzDBLHYZwT5ZJqUZdYyWqf6NdYuSe5V8K+KfD/jfwzp/jHwnq0N/pmqWcd1p97btlJoZFDI4PoQQav18sfs5399+xf8AtB3H7Fvi68lPgrxTJPqvwg1O5clYCW33OkMx/iRmLpnkhuSTIqj6npYHFPFUbzVpxdpLtJb/ACe8X1TXmTluNeNw95rlqRfLOP8ALJb/ACekovrFp9wooorsPQCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACvl/Uv+Lrf8FaNNs/9ZYfCj4VzXW7r5Op6nP5W32zajOfavqCvl/8A4J8f8XE+LXx+/aTl+dfEnxNbQ9NnPPm2Okwi3hdf9lt7fitevln7rDYrEdocq9aklH/0lSPGzT99isLh/wCapzP0pxcv/SnA+oKKKK8g9kKKKy/G/im18DeC9X8a3trJPDo+l3F9NDD9+RYo2kKr7kLgVnVq06FKVWo7Rim2+ySbb+STfyNKVKpXqxpwV5SaSXdtpJfNtL5nln7Pf/Ex/aR+NPiHr5ms6VZhv+uFmVx/49Xs9fFv7CP7V2oeLP2gPEHgzWPCsMY8eavdarFcW8jFrSVIWfymzwyeXGQDgHd7Hj7Sr4jw5znLs84ceIwk+Ze1rc2jVpSqzqde8Zwfz7po+08Qcnx+S8Qqhi48r9lR5dU7qNKEOn96El8uzQUUUV92fDhRRRQAUUUUAFFFFABRRRQAV4z+wf8A8kQ1z/ss3xH/APU11uvZq8Z/YP8A+SIa5/2Wb4j/APqa63QB7NRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXzFq3/AAR5/YM1X4keLfi3b+C/H2k6/wCO9fm1vxbd+Gfjn4v0mPUr+U5ed4bLVYogcYUBUCqoCqAoAH07RQB83fEX/gkt+w58Uvi/d/H3xR4L8bQeMb/QrLRr/wAQaB8Z/FWkz3NjaRiO3hk+w6nCHChcksCWcs7FnZmPuPws+GXhT4N/D/S/hj4HOqHSdHgMNkda8QXmq3W0sW/eXd7LLcTHLH5pJGOMDOAAOgooA8Z8D/8AKQv4of8AZGfAf/p28X17NXjPgf8A5SF/FD/sjPgP/wBO3i+vZqACvn3/AIKB/wDBPzwb+3t4N0TRtZ8a3PhzWPDlzNJo+sQWQukRJhGJo3hLpvDeVGQQ6kFB2JB+gqK6sHjMTl+JjiMPLlnHZ/h102OXG4LC5jhZYbEx5oS3X49Ndz45/wCCVOkaV+zC3jT9gjxrYix8aeHNdm1xbsuRF4k064EccWoQBidoVY4o3QE7CFyS28D7Gr5//bs/Z68aeOdJ0b9or9n9Fg+Kfw1ma/8ADbKP+Qta4/0jTJcY3pKm4KD0Y4BUOxr0L9mb9obwV+1F8GdI+MXgdmjhv4il/p8zfvtOvE4mtZRwQ6NkdBuBVhwwr0s2bzGP9px1c3aov5alt/8ADNK8ezUo9EeXlCWWy/suWigr03/NTvt/ig3yy7pxl1Z31FFFeGe8FFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB5j+1t+znYftL/AAiuPB9vqJ0zxBp1wmp+ENejJWTTNTh+aGZWHIGflbHO1iRyARn/ALGn7Rl9+0B8M5rXxzpw0zx14TvW0fx3ojAK1tfx5UyKv/POUAupHH3lBO0mvXq+X/2uPDuufswfF+w/b5+GmlTT6fHDHpfxc0WzTJv9KJCx36qOs1udvPUoACVUOT5ONTwVdY2Hw7VF3j0l6wvr3g2uiPDzFPL8Ssxgvdso1V3h0n60769XByX2UfUFFUvDfiLQ/F/h+x8V+GNUhvtN1K0jurC8t33RzwyKGR1PcFSD+NXa9VNSV1se3GSkk07phRRRTGFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBynx1+I1v8H/AIK+LfircsoXw54bvdRAbozQwO6r7ksoAHcmvNf+CaPw5uPhj+w58PNH1BW+26lov9s30kn33lvpGuyX77gJlXn+7iue/wCCr2sahcfsqJ8INCuTFqfxL8Y6P4U09k+9uuLpXcAd8xwup9mr6N0XSNP8P6PaaDpNuIbWxto7e2iXokaKFVfwAAr15fuMiiutWo38qcVFf+TTf3HjQ/f5/J9KVNL51JOT/wDJYL7yzRRRXkHshXP/ABX8V2fgb4Y+IfGN/HG8WmaLc3LRSqCsmyJiEIPXcQBjvmugrxn9ua9ub74PWXwx02Zku/G/ifT9EhKfeVZJg7t9NsZBPo1eNxFjp5ZkOJxUNZRhLlXeTXLBfOc4I9jh/AwzLPMNhp6RlOPM+0U+ab+UIyZV/Yl/Z0+H/wAMfhR4f8fxeFIU8Uazokc+o6nIztIVm/ehAGJWPCsikIFzt5ya9wqKys7bTrOHT7KERwwRLHDGvRVUYAH0AqWryLJ8HkOU0cDhoKMYRSdkleSSUpO27k0229XfVkZ3m+LzzNauNxM3KU5N6tuybbjFX2UU0kloraIKKKK9Y8oKKKKACiiigAooooAKKKKACvGf2D/+SIa5/wBlm+I//qa63Xs1eM/sH/8AJENc/wCyzfEf/wBTXW6APZqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDxnwP/ykL+KH/ZGfAf8A6dvF9ezV4z4H/wCUhfxQ/wCyM+A//Tt4vr2agAooooAK+Q/ipFL/AME8v2oD+0RpEbRfCL4o6nFa/Ea0jH7rw/rLnbDqwA+5FKTtlPqSTkmNR9eVi/EX4e+EPix4E1b4bePtGi1DRtbsZLTUbOUcSRuMHB6qw6hhypAIwQK9DLsZHCVmqq5qc1yzXePdf3ov3ovo12bPOzLBSxlFOk+WrB80Jdpdn/dkrxkuqfdI2IZoriJZ4JVdHUMjo2QwPIII6inV8t/sSfELxf8AAr4h6l/wTy+Oesy3eqeGrQ3nw08Q3ZwfEHh/JCJnoZ7cAoyj+FDgERlj9SVnjsHLA4h02+aLs4yW0ovVSXqt10aaeqNMvxscfhlUS5ZK6lF7xktJRfo9n1TTWjCiiiuM7QooooAKKKKACiiigAooooAKKKKACiiigAooooAKg1TS9N1zTLnRdYsYrq0vIHguraeMMk0bqVZGU8EEEgg9QanopNJqzE0mrM+Wf2ZdU1L9jv49XX7D3ja/lfwnrpn1b4O6tdyE/udxe40lnPV4mJZM8lSSfvoo+pq8s/a9/Zyg/aS+E0nh3SdT/svxRo10mq+C9fjO2TTtTh+aJww5CsRtbrw2cZUVB+xz+0bP+0R8LWuPFmmf2V408N3j6R450Jxtey1GL5XIXtHJjep5HJXJKmvJwbeBxH1KXwu7pvy6w9YX07wa/lPDwDeW4r+z5/A7ypP+79qn6wvePem1/IetUUUV657oUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH5Gf8ABWn4aftXfFX/AIKLr4Q+Glnr3iOS30HTtT8H6b4e8yVtGtztikmfy+LY/a45GMrFQA8eW+7j9UfhDp3jnSPhP4X0n4n6kl54ltfDtlD4ivI2BWe+WBFnkBGMhpA5z718/fsHf8Xh+P3xx/a3uP3ltrHi9fC3heU8r/Z2loI2kjP9yWRtx/2kNfUdfU8RZlOrh8PlrhFewjFNpauTinJP0ur95Xb1PkuGssp0sRiczjOT+sSk0m7pRUmotebs7do2S0Ciiivlj60K8V+Jv/Fd/tmfD/wOp32/hXRL7xFfRjoWkxbQE+6uCR9a9qrxX9n3/it/2ifiv8VW+eC11S28N6a/ZBaR5nUH3kZTXy/Ev+01cDgP+ftaLf8Agop1pfK8aa+Z9Nw5/s9LG47/AJ9UZJf46zVGPztKo/ke1UUUV9QfMhRRRQAUUUUAFFFFABRRRQAUUUUAFeM/sH/8kQ1z/ss3xH/9TXW69mrxn9g//kiGuf8AZZviP/6mut0AezUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFYnxMl+I0Hw38QT/B+z0e48Wpod23ha38RTSx6fLqIhf7Mt08IMiwGXYHKAsELFQTgUAbdFfA2rf8Edfjx+1JcP4i/4KH/8FS/jB4k1KdRLJ4I+D+rr4P8AC9grZIiW2hWSe6CEMqzzS+YwBLDOQILf/gh9f/s6qvi39h//AIKkftA/C3WIpo0tbTxT4vj8UeHZ5XcIi3GmX6BZizMqLiRW+bA5IoA/QCvk79pr9vn9rL9lrRfGfxu8df8ABPiSf4Q+A7m5m1zxTZ/FGzbW5dJgciXVbfSRbmN4RGGm8uS7jm2D/Vhvlr3n9nCL9oq3+C+i2v7WF14SuPH8AuItfu/AyXCaXdbbiVYJ4Uuf3kZktxC7xksEkd1VmVQx/O/9uf8A4KRfsZ/tkftO+I/+CdnxZ/bA8DfDT4NfD7WUtvjhe+JPFUGnal431CCUMfDVlHI6yR2KOgF7dYBlwbeI4MklAH01+2x/wUT+M/7KWt+CfEvgr9jg+Nvhj4r1zw1pl58SZPiHaabHZTazqUdjEsViYZrm4aMTQynKxIVkAD5DY+rq/On/AILuftn/ALIPw6/Zz+H3ws8R/H/wjpWsaj8TPh74p0fRZdTjSSfQYPElnK9/Eg62yRW8zbxwFib0r7u+DPxq+E37RPwz0v4y/Az4g6X4q8K60kraTr+i3QmtbsRyvC5Rxw22SN0PupHagDgfA/8AykL+KH/ZGfAf/p28X17NXzx8AvBfiTwT+378X7XxL8XPEPi+S8+Ffge5t7nxFbadE9jE2q+LgLWIWFpbKYlwSDIry5Y7pGGAPoegAooooAKKKKAPEv24f2Z9b+PPgGw8YfCrUV0r4leBb3+1/AOtAhStyuC9rITwYZ1UIwPy52kggEHc/ZD/AGmNE/an+Ddr4/t9ObS9bs5307xb4emBE2kapD8s9u6nkAH5lzyVZc4OQPUa+Sf2mNJ1T9hz9oWP9ufwHp80ngbxRJBpvxp0WzjLCEFtlvrSIOrxs22THJDdMyMw9vBNZlhvqM/jV3Sfm9ZU/SW8e01b7Z4WOTyzFf2hD+HKyqryWkanrDaXeDv9g+tqKr6Rq2l6/pVrruiahDd2V7bpPZ3dvIHjmidQyOrDhlIIII6g1YrxWmnZnuJpq6CiiikMKKKKACiiigAooooAKKKKACiiigAooooAKKKKACvlz9q3QtY/ZR+NVl+3l8PNNmm0S5SHSvjBo1nGWNzYFgsOpKg6ywHAJ6lMD5RvNfUdVta0bSfEej3fh/XtOhvLG+tnt7y0uIw0c0TqVdGB4KlSQR6GuTG4X63Q5U7STvF9pLZ+nRrqm0cGY4L69h+WL5ZxalCX8sls/TpJdYtoboWuaP4n0Sz8SeHtShvLDULWO5sru3cNHPE6hkdSOoKkEH3q3Xy5+yzrOrfskfG+8/YS8fajNL4e1BZtV+DusXkhYzWe4vPpbOessBJZR1K5PAKLX1HSwWK+t0OaStJO0l2kt16dU+qaYZdjfr2H5pLlnFuM4/yyW69OsX1i0+4UUUV2HeFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFeZftmfGhf2ev2WvHPxejuRFdaToE39mOT/wAvsuIbYf8Af6SOvTa+XP8AgoH/AMXd+L3wT/ZCtv3kPinxt/b/AImhXkHStLTz3jk9FkcgA/3o8V6OUUKeIzGnGp8CfNL/AAwTlL71G3zPMzjEVMNltSVP42uWP+KbUI/c5X+R6b+w98F2/Z9/ZN8C/Cu5tjFe2OgxTasjDkXs+Z7gH1xLK457AV6tRRXJia9TFYidafxSbb9W2/1OzDYenhMNChT+GCUV6JJfoFFFFYm5neLvEdl4P8Kan4t1I4t9L0+a7n5x8kaF2/RTXm37EPhy90T9nLRdX1cZ1DxDJPrV/JjHmPcytIrfjH5dcF/wU2+LvjP4e/CnT/BvhizC2nit7i11XUDHnyokVD5I7AyBm567UbHqOv8A2Cfih4o+Kn7O+n6j4q0mO2k0m5bS7SWGHYlzBDHGEkC9BjcUOOMxnp0r87XEOXYzxOWVe97Shh5Ne6+XmqShKWvlTUUns22k7pn6A8gx+D8Nnmnu+zr14p+8ublhGcY6edRybW6STas0e0UUUV+iH5+FFFFABRRRQAUUUUAFFFfCX7d//BWv4hfsv/tIzfBH4efDLRr+00OK1fXbrWjN5l0ZoY59luY3URgRyKN7B/mz8uBz5+ZZng8pw6rYl2i2lom9X5I8vN85y/I8KsRjJNRbUdE27vyXo36H3bRWH8MvHNl8T/ht4e+JWmWU1tbeIdDtNTt7a4x5kSTwpKqNj+IBwD7ityu6EozgpR2eq9Hr+p6UJxqQU4u6aTXo0mvwaCvGf2D/APkiGuf9lm+I/wD6mut17NXjP7B//JENc/7LN8R//U11uqKPZqKKKACiiigAooooAKKKKACiiigAooooAKKKKACmyyxQRNPPIqIilnd2wFA6knsKdWD8VPhn4F+NPww8SfBz4oaEuqeGfFug3mjeItMeeSIXdjdQPBcQl42V0Dxu67lZWGcgg4NAHyR/wUO0b48/s/8Axi0r/gp3+x/rs/i698L+GYtB+Lnwah1JGTxh4WguLi6WawQnCarZvdXUsXeZJHizyEk8y+A/jv4k/wDBbX9oDwn+1Hq+p6x4B/Za+G3iqz1r4XeFbqf7Fq3xN8QWU6y2+r30YbdFpttcRq0Fuf8AXSRiR8gBV+Rvij4F/wCDSPwT491T4cfC/wDYa8a/F3UNDu2tdZn+EFt4q1qztZlPzJ9qW/SGXH96J3Xnr1r2H/gm78Af+DYX49ftMaBp/wCzF+zXe+CvjR4N1S28R+HfCXj688SaVq8NxZyrcxXMMF5dmG6MbxeYY1MmFjYumwE0Afr1RRRQAUUUUAeM+B/+UhfxQ/7Iz4D/APTt4vr2avGfA/8AykL+KH/ZGfAf/p28X17NQAUUUUAFFFFABVLxJ4c0Lxh4evvCfijSYL/TdTtJLXULK5TdHPDIpV0YHqCpIP1q7RTTcWmt0JpSTTV0z5O/ZK8R69+x78cLn/gn58UdVnuNAvUm1P4K6/fSEm6sMlptKdz1mtySVHUpn7oMa19Y15L+2X+zHbftP/CQ6Do+rf2P4t0K8TVvA3iSI7ZdL1OE7onDAZCMRtcc8HOMquK37FH7Tlz+0j8MJ4/GukjR/HnhO9bR/H/h5wFey1CPKs6rn/VS7S6EZH3lBOwmvaxyWY4b6/Be+rKqv7z2n6T69pp/zI8PASeW4n+zpv3Hd0n/AHVvT9YX93vTa/kZ7HRRRXiHuhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAeUfth/s5N+0Z8Kv7N8N6n/ZXjDw/eJq3gjXkO17DUofmjO7sj42N1GCGwSop37H37Ry/tH/ChdZ17TP7K8WaFdvpPjbQJBtk0/UoflkXaeQjEb168HbklTXqtfLf7UOkap+yH8dLT9ujwJYTSeGtWEGk/GLSLSMtvtdwS31VUHWSEkK3cqQONztXkYxPA4j67H4dFUX93pP1hfXvBv8AlPCzBPLcUsxh8DtGqv7v2anrC/vd6bf8qPqSiq+kavpev6Ta67omoQ3dle26T2l1byBo5onUMrqw4KkEEEdQasV6yaauj3E01dBRRRTGFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAV8ufAH/i+P/BRv4tfHGX97pnw70ez8B+HpTypuCftV+R2DpLhCeu1se1fQXxb+Iuj/CD4W+I/ip4gI+xeHNEutRuVLY3rDE0m0e524HqSK8e/4Jh/DrWPA37H+geJfFoLeIPHVzc+LfEE7LgzXF/IZlcjqD5Pkg57ivYwf+z5ZiMR1lamv+3ven/5LFL/ALePFxv+05rhsP0jzVZf9u+7D/yeTf8A26fQVFFFeOe0FFFFAHh/7R2m6d8Tf2gvhf8ABrVtPgvdOW6vdd1qzuYhJE8cEJSEOjAhlZ2dSCMc17RpWk6VoWnQ6PoemW9naW6BLe1tIVjjiUdFVVACj2FeO/Df/iuP20vH3jJvng8KeH7Dw/Zydi0pNzMB7qw2n617VXynDVOnicTjsyaXNVrTinZX5KPLSir2vbmjUdr2u726n1HEdSph8PgsuTfLTowk1d256vNVbte1+WVNXte2l+gUUUV9WfLhRRRQAUUUUAFFFFABXx5qnwC+D37X/wDwUk8eX/xT8C2utaR8NfCOjaYlvI8kccuozs92sknlsvnFIy0ZR9y4IBXgY+wmZUUu7AADJJPAFfNv/BNBW8Y/D/x1+0RcAs3xI+JWq6pYzEcmwjl+z26e4Xy5APrXkZlTp4rFYfDTScXJzaaurQjp/wCTSX3HhZtRpY3GYXCVIqUXKU5Jq6tTjpdP+/OP3H0hbW1vZ28dnZ26RRRIEiijQKqKBgKAOAAOMU+iivXPd2CvGf2D/wDkiGuf9lm+I/8A6mut17NXjP7B/wDyRDXP+yzfEf8A9TXW6APZqKKKACiiigAooooAKKKKACiiigAooooAKKKKACvPP2uvhx44+MX7KHxP+EXwx1gad4l8VfDzWtH8Pag0xjFrfXNhNDBLuHK7ZHRs9sZr0OoNU1TTND0y41rWtRgs7Ozgee7u7qZY4oIkUszuzEBVABJJOAASaAPzA/YO/wCC3P8AwTC/Yr/Zf8D/ALGv7ULap+zp4/8Ah34Xs9G8T/DzxZ4C1GDZewRLHcXUU1tbyQ3Ec8qvMJt++XzN7AliaqfGj9uH9mj/AILE/ta/s8eAv+Ccfh3WvH2pfCv41aX4w8Y/GSDwjeafpfhbRLNZGvdPN7dxRPJJeqyQi3QFJPvEnyxj9BfE3xp/Y48aW8dr4x+LPwz1aKJt0Uep69p86ofUB3IFeVftUf8ABRz4JfsrWvwj8N/CFvB/jCT4jfG3w18PxpGg+K7aI6TBqtw0LX6xwLJ5ghIB8vCBiwG9aAPqGiiigAooooA8Z8D/APKQv4of9kZ8B/8Ap28X17NXjPgf/lIX8UP+yM+A/wD07eL69moAKKKKACiiigAooooAK+VP2yfB3ib9l/4uWf8AwUP+DujTXUFnbx6f8YfD1kvOraMCAL5V7z23B3d0UZKqr5+q6ivbKz1Kzm07UbSOe3uImjngmQMkiMMMrKeCCCQQeua7cBjHgsRztc0WmpR6Si91+qfSSTWxw5hgljsPyJ8sk1KMusZLZ/o11i2nuUfBvjHwz8QvCem+OvBesw6jpOr2Ud3p19btlJ4ZFDKw+oPQ8joa06+RvgJe3v7A37SZ/Y+8VXcn/Cs/Ht3Pf/CDU7mQlNMvGbfcaK7HoCzb4snksBlmkO365qswwawdZcj5qclzQl3i+/mneMl0kn0aJy3GvG0H7RctSD5Zx7SXbvFq0ovrFrqnYooorgPQCiiigAooooAKKKKACiiigAorxn9vHwl8WfGn7P11ovwgju5rz7fE+p2dgx866swrh40A5Y7zGSo5IUjnofM/+CY9/wCNfCv/AAlfwh+JE2oadeWi2l7pfh3WIJIZ4Yn8wSyokgBCEmLOOAef4ufisXxhPB8aUMhqYWfJVjdVtoc1pNQWlm/da+JS5rWi1dn2WE4ShjODq2eQxUOelKzo7z5bxTm9bpe8n8Lja95J2R9ZUUUV9qfGhRRRQAVU8QaBovirQr3wx4j0yG90/UbWS2vrO4TdHPC6lXRgeoKkgj3q3RSaUlZiaUk09mfL37Juv61+yv8AGW+/YK+I+pzT6TJHLqvwg1q8fJvNNLFpdOZj1ltzkgdSmThV2A/UNeR/tk/s5XX7Qvwwj/4Q3UhpfjfwveLq/gXXEIV7PUIvmVC3/POTARgcjlWIO0Crf7Iv7Rtr+0p8JIfFGoaadL8S6VcvpfjLQZAVk03U4TtmjKnkKT8y5/hYA8g48rBN4Ku8FP4d6b/u9Y+sL6d4Nfys8TL28uxLy6fw2cqT7x6w9ad9O8HF/ZZ6jRRRXrHuBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAfMf8AwVI1O/8AFfwl8Kfsu+Hrp49R+LnjrT9BkMJw8Ngsqz3c/wDuqsaBvZzX0rpemWGi6Zb6NpVqkFraQJDbQRjCxxqoVVHsAAK+VNE8U+GP2mv+CqCXfh3xHYarofwU8BSiGSyu0mRda1GTy5dpUkHbbrsbHKum04PFfWVezmUZYbB4fCtWai5y9aj0+6EY/eeJlco4rG4nFp3TkqcX/dpqz++cpfcFFFFeMe2FNmmit4XuJ5AiIpZ3Y4CgckmnV57+1f41Pw//AGcvGHiWOXZKNFktrZweRLPiBCPcNID+FcWZY2nluXVsZU+GnCU36Ri5fpb5nZl2CqZjmFHCU/iqTjBespKP63+RzP7DkMus/DDWfivdxsJvG/i/UdXBcfMIjMYo1+gEZx9a9orl/gn4LHw6+EPhrwOYtkmmaJbQTjGMyiMeYfxfcfxrqK4eGsFUy7h/C4er8ahFy/xyXPP/AMnnI7uI8bTzDPsTiKfwOcuX/BH3If8AkkIhRRRXtnihRRRQAUUUUAFFFFAHmP7aPxK/4VD+yj4/+IEdx5U9n4YuY7KTONtzMvkQn/v7IlWf2Rvhr/wqD9mLwJ8OZLfyp9N8MWi3qYxi5eMST/8AkV3NeY/8FI/+K30H4a/s5w/P/wALB+Jum2upQf3tOtmNxctjvt2RHFfSdeXS/fZvVn0hGMfnJub/AAUTxqH7/Pa0+lOEIL1k3Ul+Cggooor1D2Qrxn9g/wD5Ihrn/ZZviP8A+prrdezV4z+wf/yRDXP+yzfEf/1NdboA9mooooAKKKKACiiigAooooAKKKKACiiigAooooAK4D9q74Nf8NF/st/Er9nz7QsX/Cd+ANZ8O+azFQn22xmttxI6Y83Oa7+sP4m+G/E/jL4b+IfCHgnx5c+Fda1XQ7uz0jxPZ2cVxNpF1LC6RXiRTAxyvE7LIEcFWKAMCCaAPz7/AGJP+Dc//gnj4f8A2Svh94e/bC/YR8DXnxO07wzb2njW/stVvJ47y+iXy3uA6TKrGQKJDhQNzkYFWfj/AP8ABvR+x7oXjf4K/FT9gv8AZr8D+BPFHw/+PvhXxZ4j1ebUb5Hn0HT7z7ReW0OTMHmfbEUVgoJXl177+r/tO/8ABdH9kqQ+Gfiz+wD4P/aS0i3Oy1+IPwf8axeH76eIcK93pGoByJ2xlhbyGJSeOOKZpn7cP/Bbf9o6QeGPgL/wSW0T4RpMdr+O/jt8S4Z7Wz9T/Zmmp9qmbHIwyrnAJAyaAPvuvhv/AIKN65+3T+xv8CPiX+3Pof8AwUFtvsvhCSXVPDPwr1H4aaWui6jAbhVtdGlnCtqEt1PuS3WeK4jzLIpEQHy19Wfs3+BPjF8Nfgvovg74/wDxr/4WJ4xtxcSa74vGgw6Yl7LLcSzBY7WElIYokkWBFyzbIVLMzFmPxD8ZtM/b2+Lv7fV38UP2g/8Agmn4+8c/C34Va7v+BvhTwt498IJpl/fx7l/4SjUUvtYgllusE/ZYHiVbVWL4MzFlAPQdZ+Kv7Zf7Z/7X3xC/Z9+AX7Q0/wADtG+EHgzw7Prc9r4Q07Wb/VfEWsWst6ttP9vjkjSztrdIA6RLHLI87YlQKK9i/wCCbX7UPi79sT9jLwh8c/iPodjpvim4fUdI8W2Wmbvs0eraZqFzpt40IYlliee0kkRSSQjqCSRk+QeIvBf7ZX7Ln7ZHxH/as+AX7I1z8T9F+OXhDw9JrXhi38baVpWoeF/EWl20tqone7mWGa0lt5IFeSB5ZEe2bbHIrAn17/gmz+y94v8A2O/2MfCHwM+I+t2Oo+KYH1HV/Ft7pm77M+ranqFzqV4sJYBmiSe7kjRiASiKSATgAF7wP/ykL+KH/ZGfAf8A6dvF9ezV88fAL4R/Cj4Qft+/F/TfhN8MfD3he21T4V+B9Q1O38O6LBZJeXkmq+Lg9xKsKKJJWCqDI2WIUZPAr6HoAKKKKACiiigAooooAKKKKAPN/wBq39m7wt+1T8GNR+FfiK5eyumZbvQNagyJtK1GLJguoyCCCrcHBBKsy5Gc1yP7DH7SPin4u+E9V+EnxttksPil8O7tdK8baecD7SQP3OoRdN0U6AOCABuzgBSufdq+Yv25vhb41+GXi7Sf2/P2f9Ha58VeCbUweMtDt/l/4STw8TunhYDrLEAZEPJG3oxRFr2cvnDGUXl9V2u702/sz7N9Iz0T6KXLLueJmVOeCrrMaKvZWqJfah3S6yp6yXVx5o9j6dornvhP8UvBPxs+G+jfFf4dawl9ouu2KXVjcL12nqjD+F1YFWU8qykHkV0NeROE6U3Cas07NPdNbo9inUhVgpwd01dNbNPVMKKKKksKKKKACiiigAooooAK8r/aV+D/AIi8Uw6f8XPhO62/jrwkxn0iToNQg582yl/vI4Jxnox6jcTXqlFefmmW4bN8DPC172lazWkoyTvGcX0lGSUovo11TafflmY4nKcbDE0bXV7p6xlFq0oyXWMotxkuz6NJrkvgl8YPDvxv+H9p450BGgdyYdR0+b/W2N0nEkDjggqfUDIIPeutrwX4t6ZqP7MHxQk/aR8H2MsvhXXJUh+IukWyE+SxOE1KNR/EpOHA65J6sWX3PS9U07W9Mt9Z0i9iubS7gWa2uIXDJLGwBVlI6gggg152RZlia/tMBjrLE0bKVtFOL+CrFfyzS1X2KinB7Rv6Gd5dhqHJjsFd4atdxvq4SXx0pP8Amg3o/twcJreVp6KKK+hPACiiigAr5Z/aU03UP2Nvj9bftt+DLGVvB/iJoNK+MOlWsZIRCwS21dUHV42YI+OSDgDLsw+pqo+JvDWg+M/Dl/4R8U6VDfabqdpJa39ncLuSeGRSrow9CCRXHjsK8VRtF2nF3i+0lt8ns11i2uxwZjgnjcPaD5akXzQl/LJbP0esZLrFtdixpupafrGnW+r6TexXNrdQpNbXMEgZJY2AZXVhwQQQQR1BqavmD9kPxLr37M/xa1D9gT4n6rNcWltBJqfwl1u7bJ1HSCSXsmY9Zrc5GOpQEgBVXP0/TwWKWLoczVpLSS/lkt1+qfVNPqPLsasdhudrlmm4yj/LJbr9U+sXF9QooorrO4KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK5X466LN4k+CHjLw7beKv7Ckv/AArqNtHrmSP7OZ7aRRcZXkeXnfxz8tdVXzz/AMFQfiBrXhP9krVPAvg98+IfiLqVp4P8PwhsGWe/k8t145/1Am6d8V25bQnicwpUoOzco69tU2/RJNvyWpw5nXp4XLq1WaulGWnfRpJebbSVtbvTU+Kf+CLP7D/7ROm/Gnw/+15rkA0XwSdJvGs3e/RpNcWWOW3VPKRi6IsmJcyhcmJCoOQR+rlYXwv+H+i/Cj4baB8MPDibbDw9o1tp1p8uCY4YljBPuQuT7k1u13cQ51Wz3MpYmaSS92Nlb3U3a/d66/5Hn8OZHR4fyuOFpttv3pNu/vNK9uyutPvd2wooorxD3grxX9sT/iqrz4d/BuP5v+Em8cW0l7F132VqDNMMf98H8K9qrxW//wCK6/bvsLbG+18C+B5bjd/zzvLyTy8e2YRn8K+X4u/fZXDBLfEVaVL/ALdlNSn/AOU6cr+T8z6bhT9zmc8Y/wDmHp1an/byg4w/8nqRt6eR7VRRRX1B8yFFFFABRRRQAUUUUAFFFVNf13R/C2hXvibxDqMVnp+nWkl1fXc7YSCGNS7ux7AKCT7Ck2krsTaim3sj538Xf8XR/wCConhPQB+8s/hh8OL3WHbqsd9qEotQh/2vJAcewr6Tr4f/AOCff7XHwV+Nn7afxf1i21q5TXPG17aDwpFeWxRbnS9Pt2jAQ5+WQrmVkIBwM8kMB9wV4+SV6OLoVMRTkpc9Sb08mopf+AxT9GeBw7icPjsNWxVKal7SrN6O+zUYr/wGKfpJBRRRXsn0AV4z+wf/AMkQ1z/ss3xH/wDU11uvZq8Z/YP/AOSIa5/2Wb4j/wDqa63QB7NRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFfA37cvhn4jftw/wDBTnw1/wAE2dT/AGjPG3w3+GWl/A+X4ieJovhzrZ0vVPFl2+rnTYrF7xQXjtYFTzZET75nQN/CyfPn7Mnxy+LvhH/glD/wTm+KGjfGLxOniDxB8evD3h/XIR4guT/wkem6jc6nbXkF5HvxdokWJx5gbyzbBhgigD9fKKKKACiiigDxnwP/AMpC/ih/2RnwH/6dvF9ezV4z4H/5SF/FD/sjPgP/ANO3i+vZqACiiigAooooAKKKKACiiigApGVWUqwBBGCD3paKAPkLwgx/4J0ftTj4Z3beR8GPi7q7S+F5mOIfC/iF+Xss9I4LjGUHADAAABZGP17XFftDfAfwL+0t8H9a+DPxEtC+n6xbFFnjA820nX5oriMno6OAw7HGDkEg+V/sJfHjx1qg1v8AZM/aIux/ws34bFLe9unJxr+lnAttTiJ5cMpUOeSGILYL7R7mJ/4VMH9bX8Wmkqn96O0anrtGfnyye7Z4OF/4Scb9Tf8ACqNun/dlq5U/TeVPy5or4Uj6Jooorwz3gooooAKKKKACiiigAooooAh1LTrDWNPn0nVbOK4tbqForm3mQMkqMCGVgeCCCQRXhXwq1G//AGWvinH+zt4rvJJPB/iCeSb4earcOT9mkJy+myMe4JyhPXIHJbC+91ynxq+EXhv43fD+88B+I90Xm4lsb6IfvbK5XmOeM9Qyn3GQSOhNfPZ7lmJxHs8dgbLE0buF9FOL+OlJ/wAs0tHryTUJraV/fyTMsPQ58FjbvDVrKVtXCS+CrFfzQb1X24OcHvG3V0V5T+zV8XvEniIaj8Gvi3th8c+EyItS7LqVtwIr6P8AvK4I3Y6MRkDcAPVq9HK8zw2b4GGKoXSd009JRknaUJLpKMk4yXddU035+Z5biMpxssNWtdWaa1jKLV4yi+sZRacX2fRppFFFFegcAUUUUAeP/tnfs56l8fPhtb6l4A1EaZ498IXo1jwJrSkK0F9Hg+SzH/llKFCMD8v3WIO3B0/2S/2i9N/aY+EFt42bTjpuu2M76d4s0KQFZNL1OH5ZoWU8gZ+Zc87WGecgem18r/tDWV5+xX+0PB+2V4VtJP8AhBvFssGl/F3TbZCVtXLbLbV1Ud1ZgkmByG6FpCR5GLX1DEfXI/A7KovLaM/+3b2l/cf908LHp5Zi/wC0I/A7Rqry2jU9YXtLvB3+wfVFFRWV7Z6lZQ6jp13HPb3ESyQTwuGSRGGVZSOCCCCCOualr19z3U01dBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXy38Yv+L7f8FMfhv8ACWM+dpHwq8NXfjHW0HKNf3BFtZRt6On+uX2Y19RsyqpZmAAGSSelfLv/AATdB+LGu/Fn9su7HmD4jeOpbXw9Oed+i6aDa2rA9skSggcZQda9jK/3FDEYv+WPLH/FU938I87PFzX/AGjEYfBr7c+aX+Gn734y5EfUdFFFeOe0FFFFABXiv7KP/FXePvip8YnG4ax4yOmWch/jtrCMRIw9juP5V1P7TXx60f8AZ0+Fdz4+1OykuZ5ZxZ6Xax8ebdOjsgYn7qgIzE88L0JNecf8E1/if4X8Y/Ar/hB9Ktp4tT8OXLHWGnO7z3uZZZVmDd84ZcHkbO/Br4XM84yytx3gMplVXtYQq1eXq5OChBbWvyurNK+ybPt8tynMqPBGOzSNJ+znKlS5uiipuc3ve3MqUHpu0j6Iooor7o+ICiiigAooooAKKKKACvLv22fGnhvwB+yP8RvEfi2FZbE+Eb20e3Zyone4iNvHFkcjfJKi5HPzV6jXzR+3b/xd74r/AAh/ZFtv3kHiXxX/AG94oiHI/srTV85o5PRZZCFB/vR15+aVZUsBU5fikuVesvdX/pV/RM8vOq8qGWVeTWUlyR85T9xfjK78kzgP+Cd//BK7Sf2dvE/h/wDaR8d+O7nUvEZ0FJrTRF04W8ek3FzbbJld/MYzsqyPGDhByTgnGPtaiiqy7LcJleGVDDxtHd+b0u362/yKynKcDkuDWGwkOWO73u3ZXbv1dv0WgUUUV3HpBXjP7B//ACRDXP8Ass3xH/8AU11uvZq8Z/YP/wCSIa5/2Wb4j/8Aqa63QB7NRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAfDP7dXwS+E37b37f8A4b/Zcj13x78Lvit4E+EsvjrwL8dPh74iSyvra2uNSOnXWk+UyMLqAlIpJUf5QJYwCvmMWqf8E+/+CD/ww/Yq8VeCfGnxI/ah+IXxfuPhbZXNr8KdE8W3EUGi+ERcBhNcWljECv2lld1852YgNwAVVgn/AAVr/wCCfvhf44/FTwp+2n8Q/wDgqd4l/Zw074daL/Z2k6ppmpWGmW9pcTSzNPN9uuHjdTcI0MTwb/LkW1iyrEVxH7En7Pmq/Gr4o6N47+Bv/ByJ40+NOn+ENdsdS8ReENI1fRL6K9tYrhHe1u1tyZYoZgpiLYBIc4OaAP0pooooAKKKKAPGfA//ACkL+KH/AGRnwH/6dvF9ezV4z4H/AOUhfxQ/7Iz4D/8ATt4vr2agAooooAKKKKACiiigAooooAKKKKACvnX9u74E+Or46J+1x+ztZ5+Jnw23z2tpGDjxBpRybnTJQvL7lLNGOSGLBcM4YfRVFdWCxdTA4mNaGtt09mno4vyaun9+6RyY7B0sfhpUZ6X1TW8WtYyXnF2a+7Zs4v8AZ7+O3gX9pT4QaL8Zvh3eGTTtYtQ5hkI820mHyy28gHR0cFT24yMggntK+QfFIP8AwTn/AGqD8QrUGD4L/F7WFj8RxLxB4X8RPwl5jpHb3GMOeApBJICIp+vgQwDKcg9CK6MxwlOhONWhrSqK8X1XeL/vQej7q0tpHPlmMq4iEqVfStTdppbPtJf3ZrVdnzR3iFFFFeaemFFFFABRRRQAUUUUAFFFFAHk/wC0t8JPE2tnTvjX8IVWLxx4TzJYLj5dUteTLYyY+8GGdvoxOCN24dd8GPi54a+Nvw/svHvhksiTgx3llKf3tncLxJBIOzKfzBBHBFdVXgfxRsL79lb4qyftBeF7OR/BniO4SH4g6XboSLOYnampRqPc4kA65zyWyvx+ZRlw5mEs2pr/AGepb6xFfZeijiEv7qtGtbeHLU3pu/1uXNcQ4COV1H+/p39hJ/aWrlQb/vO8qN9p80Nqit75RUOn6hY6rYQappl3HcW1zEstvPC4ZJEYZVlI4IIIINTV9fGSkk07pnybTi2mrNBRRRTEFZ3i7wn4d8d+F9Q8F+LtJhv9L1WzktdQsp1yk0LqVZT9QT71o0UpRUotNXTFKMZxcZK6Z8x/sdeLPEX7O/xO1H9gL4r6tNc/2VbtqHws1u7bnVdEJJ+zFu81vypUfwqcAKgJ+nK8b/bS/Z11n44/D6z8TfDS+GnfELwVe/2v4F1YEApdJgtbOTwYplUIwPy52k5CkHc/ZT/aJ0X9pv4PWXxCtLE6fqsEr2PibRJQRLpepRYWe3dTyMN8y55KspODkDysDJ4Os8DN6JXpvvHrH1ht5xcX0Z4mXSlgMQ8uqPRK9JvrDrG/endLu4OL6M9Iooor1j3AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAPFf+Ch/wAYLz4J/seeNfFGiO/9r3+m/wBj6FHD/rXvbxhbRlB3ZfMMgH/TM12P7M3wfs/gD+z94P8Ag3aIgPh7QLe1uXj6SXAQGeT/AIFKXb/gVeK/tcf8Xu/bY+CP7MEP72w0O8n+IHiqHqFiswYrHcO6tcM6kHjkda+o69jFf7NlNCh1m3Ufp8EPwUn8zxcJ/tOcV6/Smo0l6/HP8XBfIKKKK8c9oKKKKAPCv25NMsviPpXgv4ALAr3vi/xZDiQKDJa2tupe5nTIOGVGx9Gau4+AX7OPw2/Zw8PXPh/4ewXbm+mEt9fahMsk9wVBChiqquFBOAFA5PcmuP8AA/8Axdb9svxP44b95pvgDR4tC0w/wm9n/e3Lr/tKP3R9iK9tr4nI8twGZ55is/qUoupzulSm1qqdJezk0/79T2mu9opJpaP7PO8xx2W5Lhsip1ZKnyKrVino6lV+0imv7kPZ6bXk203qiiiivtj4wKKKKACiiigAooooAK+aP2bv+L2/tx/Fv9oaX97pvhFIPAXhmXqA0JE9/jtkTlcEdmr2X9ob4sWPwL+Bvir4u35TGgaJPdQxydJZwpEMf/A5Ci/8CrjP2APhNffB/wDZO8J6Jr4dta1WzbWtflmH7yS8vGNw+/1ZQ6xn/rnXl4n/AGjMqNHpC9R/L3Yfi5P5Hi4z/as3w+H6QTqy9V7kP/JpSl/26ey0UUV6h7QUUUUAFeM/sH/8kQ1z/ss3xH/9TXW69mrxn9g//kiGuf8AZZviP/6mut0AezUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH5qf8FB/D37J3xH/AOC1/wAJvh5/wUpm0Gb4VRfBC9vvhVo/j+5SPw5qPjP+1xHeJMsxEE9wtj9l2RTZU+YcAsUB5f8AbR+GP/BOT4L/ALdX7Kus/wDBO3w98OPDPx21D436XY6jo3wfjs7WW+8GSRT/ANtvqNrYYjNutsCwllXduQBCQr4+sv2nbr9lf9sD9rG1/wCCX37Rv7L2j/EGzPwwf4hahqHiGKKS30mL+0P7Ot1hBXzVuJX+0YkjZCqROMndg8UP2e/+Cdn/AARn8W/DjxF+zr+xB4f0KX4tfE7Tfh9deKtIYvf6XLqIl+zM01yZJmt3nhjjaNJFG6SNiG28AH2tX59f8FtP2UvgJqeq/B39rrUvAz3HxC079ob4a6Rp+uz6vdutrZnxLbbkitjL9njZhI4aRYw7A4LEAY/QWvlX/go3+wp+1L+25feGNF+F/wC2P4a+HnhTw14h0LxJHoupfCRtcup9b0vUTewXBuhqtqFgYpbo0HlE/u3PmfPhQDxr/gpRP+zLd/8ABSX4e6B/wU71vSLT9nqf4QanJ4Si8c6gbbwvceNF1GLzheszLA1yun7TbLcHHM5j/eV0P/BAX45p8Xf2fPi74L8MaxrWoeBvhv8AtCeIvDXwqu9fe4e4HhcR2l7p0W+5/fPGkV7tiMhLCDyR2AHuPjz4Fft7+J/hr4W8O+Hv23fBOneI7C2uY/GOs3nwOF5Za1I8qtBNb2baqrWTxINozNOrE7ivAA6z9kT9lnwt+yN8KJvh7ovinU/Eeraxr994h8ZeLtbEYvfEGtXsplu76ZYlWNCzYVY0UJHHHHGowgoA4n4BfE7w38Uf2/fi/qHhrTfENtHp3wr8D2NwviLwjqOju8qar4uJaJL+CFp4vmGJow0THIVyVOPoevGfA/8AykL+KH/ZGfAf/p28X17NQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBzvxb+FXgn43/DbWfhP8RtIW+0XXbF7W+t24O08h1P8LqwDKw5VlBHSvBv2Gfip42+HHivVv2Bv2gtXa48WeB7VZvCOuXHH/CS+HidsFwpP3pYgBHIMkjaOWKu1fTdeEftz/s3+Kvi14W0n4wfBC4Sw+KXw6u21TwXf4x9rwP32ny8jdFOgK4JA3YyQpbPr5bXpVISwWIdoTd039ieyl6P4Z/3WnvE8fM6FalUjj8Or1IKzivtw3cf8S+KH95NbSPd6K85/ZU/aQ8K/tUfBfTfit4bt3s7iQta67o0+RNpWoRYE9rICAQVbkZAJVlbAzXo1ebXoVcNWlSqq0otprs1/X69T0sPXo4qhGtSd4ySafdP+vzW6CiiisjYKKKKACiiigAooooAKr6tpOm69pdzoms2MV1Z3kDw3VtOgZJY2BDKwPUEEirFFTKMZxcZK6ejXdMcZShJSi7Napng3wf1bUv2Zfien7NPjO+ll8MazJJP8OdYuXJ2c5fTZGP8AEpOUz1BA/iVR7zXI/G/4PeH/AI4fD+68E65I9vKWE+l6lDxLYXacxzoRggg9cEZBIzzXNfs1fGHxB4uttQ+FPxVjW28deE3FvrUPQX0X/LO9i6bkkGCcdCegDKK+SyuUuHcwjlFV/uJ3eHk+ltZUG+8FeVK796neGrpa/WZnGPEGAlm1Jfv4WWIiut9I10u03aNW3w1LS0VTT1Oiiivrz5IKKKKACvlb4721z+xD+0fF+1v4dt3X4e+ObiDTPixYwISmn3RbZbauFHTltkhHXcThmkBH1TWX418GeGfiJ4R1LwJ4z0iK/wBK1eyktNQs5h8ssTqVYe3B4I5BwRyK4sdhXiqK5HacXzRfaS/R6qS6pvsjz8ywUsZQXs3y1IPmhLtJd/7rV4yXWLfVI0bW6tr22jvLO4SaGZA8UsThldSMhgRwQRzmn18zfsZeMvE3wI+Iep/sB/F7V5bm68P2xvvhrrd0cHWdBJO2LPQzW+ChUfwqcDbHk/TNXgsUsXQU7Wa0kusZLdfJ7Pqmn1Ly/Gxx+GVS3LJNqUesZLSUX6PZ9U01owooorqO0KKKKACiiigAooooAKKKKACiiigAooooAKKK8B/4KUfteap+xf8Asz3HxL8N6Et/rOq6pHo2ieaxEVtczQzSCeTHJVFhc7RjLbRkAk104PCV8fi4Yairzm0l6v8Ap/ccuNxlDL8HUxNd2hBNv0X9JfM5n9iX/i9P7Unxx/axuP3tm3iGPwV4UlPRbLTlH2h4z3SWdlfPqpr6kr4f/wCCFP7Qtj8Tv2atS+DCeEvsF34AvUNzqCSFl1IX0tzMJWLc+aGSQNyRjZjHQfcFenxJRq4bOatCatycsUv7sYpRfzXvesmeVwxWpYrJKWIg7+05pt/3pSk5L5P3fSKCiiivDPfCsb4ieNNN+HPgPWPHmrkfZ9I02a7kUnG/YhYKPckAD3IrZrxT9sqebxla+EP2d9OlYTeOvEkUeoKjYYabbET3LDHphPrzXjcQ5jUyvJa2IpK9RK0F3qTahTXznOPyTPXyDL6eZ5xRw9V2pt3m+0Ipzm/lCMvm0a/7GngvUvCnwI07WfEIJ1jxRcS6/rEjDBee6bzAT6ER+WCPUGvVKbBBDawJbW8SpHGgWNEGAqgYAA7CnV05Tl1PKcro4Km7qnGMb92lq35yk5SfnJmGa5hUzXM62MmrOpJyt2TeiXlGKjFeUUFFFFegeeFFFFABRRRQAUUUUAfNH/BQZj8VfEvws/Y/syZF8feMkvfEUK850bTgLm4VvTcwj2k8EoRzX0sqqqhVUAAYAA6V+XvwT/4KSz/F3/gpzovxD8QfDkf2ZrUCeDPDdqJW8/TIbi7UpcsD8rSM7fvMAYRiATt+b9Q6+fyPHYXNKuIxNGV/eUfSMV7v33lI+X4czLBZzXxeMoS5vfUNmrRhH3d/5m5y+avqFFFFfQH1AUUUUAFeM/sH/wDJENc/7LN8R/8A1Ndbr2avGf2D/wDkiGuf9lm+I/8A6mut0AezUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFeW/tyfE7xJ8Ev2KfjB8Z/BkjprHhH4W+INa0po1ywubXTbieIgdzvjWgDwT9vv8AZe/bY8PftVeE/wDgo3/wTph8J69470TwTP4L8b/DjxxfPaWfinQHu/tkK290vFtdwXJkdWfCsJSCcApJ574c+Cv/AAVb/wCCif7Q/wAL/F37f3wI8DfA74U/CLxva+NbbwVoHjJNf1nxNr9mr/YGluYAIYbSGRzKV+8zKAQ2Q8eX+2V+1/8AHL9j/wD4N4PCXxe+H3xZ1XxF8WfGfw88KaP4c8XajeG4vb/W9aS2827SR8kyKk1zNF12mOMdFrzm7/4J+ePf+CNHxT/Zv/aF+FH7aPxa8bar49+MmgfD7416J458WvqGl+JV1oSQPfxwOoMUsFyFkjJZ2CdXOH3gH600UUUAFFFFAHjPgf8A5SF/FD/sjPgP/wBO3i+vZq8Z8D/8pC/ih/2RnwH/AOnbxfXs1ABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB8i/Hazu/2A/2lh+134XtZB8MPiBeQ2Hxc023QlNKvmbZb60qjoCzbJcDksT8zSLt+trO8tNRtItQ0+6jngnjWSCeFwySIwyGUjgggggjrVDxr4M8MfETwjqXgPxro0Oo6RrFlJaajY3C5SaGRSrKfwPUcjqOa+Z/2MvGfif9mT4s3v8AwTu+MmszXUen2z6h8IPEN43Or6ICSbNm6Ge2wRtH8CnACopb3J/8KuB5/wDl9RWvedNaJ+cqeifeFn9lngw/4SMf7P8A5c1np2hUerj5RqatdFO6+2j6rooorwz3gooooAKKKKACiiigAooooAK8k/aV+FHie9udP+PPwdhC+NvCiloYAPl1ey6y2UgH3sjJT0YkDBII9borzs1yzD5vgZYatdXs1JaShJO8ZxfSUZJNP1TunJP0MrzLEZTjY4mlZ2unF6xlFq0oSXWMo3TXo1ZpNcx8H/iv4X+NXw/sfiB4UmPkXabZ7aQ/vLWdeJIZB2ZTx7jBHBBrp68C+Itnd/smfFeT45eHraRvAnim7SLx1p0CEjTbpjtTUUUdFJOJAOpPcldvvNneWmoWkV/YXMc0E8ayQzROGWRGGQwI4IIIINcGRZniMUqmDxtliaNlNLRST+CrBfyVEr215JqcHrFX7s7y3D4ZwxmCu8NWu4X1cWvipSf89Nu19OaDhNaSdpKKKK+gPBCiiigDxb9tf9nnxB8ZfAth46+FF0th8RvAl5/a/gjUhgFplAMlm5PWKdV2FScZ25+UEHpf2W/2hvD/AO038HdP+Jmj2rWV7ua01/R5ciXS9Riws9s4PIKtyMgEqynAzivRK+VPjRDN+wx+0vH+1FosTR/DX4h3kOn/ABQtIl/d6VqLHbb6uFH3VYnZKfViTuZ1x5GK/wCE/E/XF8ErKp5dIz/7d2l/daf2Twsb/wAJeM+vx/hytGqu3SNT/t2/LP8AuNN/AfVdFNhmhuYUuLeVZI5FDI6NkMDyCCOop1eue6FFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFfG/iLwh4f/wCCmP7WGq+H/F1i2pfBf4QyTadLbLcSRw+IfEkkZSYh42ViltG2AVIIcgglZDXpn7fnx98X/DP4faZ8Hfgq3m/Ev4m350PwbAjYa13AfaL9sfdSCNt27naxUkEBq9C/Zq+AfhD9mT4J6D8FvBa77bR7QLcXjriS9uWO6a4f/aeQs3sCAOAK9zCSlleCeMTtVqXjT7pbTmuz+xF93JrY8HGRjm2OWCavSp2lU7Se8Kb7r7c12UE9yT4Efs5fBP8AZl8IP4E+Bnw/tfD+mS3BnnhglklkmkIxukllZ5JDgADcxwOBgV21FFePVq1a9R1KsnKT3bd2/Vs9qjRo4ekqdKKjFaJJJJeiWgUUUVmaBXiXw9/4ur+2J4t+IL/vNN8C6XF4d0puqm7kPm3Tj0Zf9WfYivUfiX440/4a/D7WvH+qYMGkabNdMhON5RSVQe7HCj3NcV+xz4I1Dwb8BdKvdfy2r+IpJNc1mVhhpLi6bzMsPUIY1PutfLZt/wAKHEGCwC+GnzYif/bnuUk/WpOUv+4fkfT5X/sGQ4zHP4qlqEP+3/fqtelOEY/9v+Z6jRRRX1J8wFFFFABRRRQAUUUUAFcl8ePirpnwP+DHif4uavtMPh/RZ7xY3OBNIqHy4vq77UHuwrra+aP+Cgzv8V/EPww/Y5sXLj4geLkvPEkSnP8AxJdPxc3Ct/d3MI9pPBKEc1xZjiJ4bBTnD4to/wCKT5Y/i19zPOzbFTweX1KlP47Wj/ik1GP/AJNJP0TKP7AH7Cvwh+HPw48IfHzxt8PYLr4mappp1TU9cvJpWeGW7Zptqwl/KidEkWMsqBuDzya+paRESNBHGgVVGFUDAA9KWqwWCw+Aw0aNGKSVr2Vruyu33b3bLy7LsLleEjh6EUkkr2SV3ZJyfdvdt66hRRRXWdwUUUUAFeM/sH/8kQ1z/ss3xH/9TXW69mrxn9g//kiGuf8AZZviP/6mut0AezUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFUvEvhvQfGXhzUPCHirSYL/S9VspbPUrG5TdHc28qFJI3B6qysQR3Bq7RQB+eHwo/4N5Phj4A+LfgHUvGv7aXxf8AHPwo+E3iaPxB8L/gn4r1lLjSNEvoSxtdz433EVuWIiQgFV+Usys6v9UftS/sc6X+1T8UPg5418WfEG+sdG+EfxAHjFPDVtZo0es6nDbSw2Tyyk7o1gaaWQBQdzEZxtBrw39qH/g4M/4Jm/sr/GDUvgBrnxP13xj4y0SZote0L4c+FbnWH0yRTh45pYlEIdTlXQOXRgVYKeK9I/YQ/wCCtH7CX/BR641TQf2X/jGL3xFoUXm634P1zTJ9N1ayj3BTI1vcKpkjDMqtJGXRWZVZgSBQB9I0UV4X8d/+ClX7E37M/wAc/Dv7Nfxp+NqaT438VXum2mi6FB4f1G9aSW/ufstmJZLW3kjt1lmyivMyLkckDmgD3SivLf2k/wBtH9mv9kh9Ds/jv8Q5NO1DxNLPH4d0LSdBvtX1PUzCoaZoLHT4J7mVI1ZS7rGVTeu4jcM7v7P/AO0Z8E/2pvhvB8W/gD8QrPxJoE91Nam8tUkje3uYXKTW88MqrLbzIww0UqK6nqozQBx3gf8A5SF/FD/sjPgP/wBO3i+vZq8Z8D/8pC/ih/2RnwH/AOnbxfXs1ABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAV41+2x+zHd/tHfDK3uvAuqjR/H/hG9GsfD/xAhCtZ6hHgiNm/wCeUu0I4OR91iG2AV7LRW+FxNbB4iNak7Si7/8AAa6pq6a6ptHPisLRxuGlQqq8ZKz/AEafRp2ae6aTPJv2Nf2nLT9qD4Rr4j1XSTo/ivRLt9J8ceHJQVl0vVIflljKnkIxG5DzwcE7lYD1mvk79rHw7rn7HPxzt/8AgoD8MNKnn8O6gsOmfGvQLGMsbixyFh1ZEHWaAkBj1KY+6DI1fUnhzxFoXi7w/Y+KvDGqwX+m6laR3Vhe20gaOeGRQyOpHUFSCD7125lhqK5cVh1+6qXsv5ZL4oP0vePeDT6M4csxVaTlhMS71adrv+eL+Ga9bWkuk1JbNF2iiivLPWCiiigAooooAKKKKACiiigCrrei6T4k0e68P69p8V3ZXtu8F3bTLlJY2BDKR6EGvEvgtrerfs4fEpf2XvHeoSzaDqJef4b61dNnfFnL6fIx/wCWkefl9QQOMote71xvx1+DeifHDwDP4Q1O4e0u45FudG1WHiXT7xOY5kI5GDwQCMgkZHUfO57luKqunmGAS+s0b8qvZVIPWdKT7TteLfwVFGW3Pf6DJMxw1JTwGOf+zVrcz3dOa0hViu8b2kl8dNyjvy27KivMP2a/jJrnjrTr/wCHHxOt0svHPhSQWviC06C5X/lneR9N0cgwcjgE9ACufT69PLMywubYGGKw7fLLo1ZxadpRkukoyTjJPZrtZvzcyy7E5VjZ4Wuvej1WqkmrxlF9Yyi1KLW6fqkUUUV3nCFZHj3wL4W+JvgvVPh7430iO/0nWbKS01C0lHEkbjB56gjqCOQQCORWvRUyjGcXGSumTOEakHGSuno13T3Pmn9izx14q+DfjbVf2CPjLq0lzqvhS2+1+ANbuuDrnh8kiLB7ywY8tlHZcDIjLH6WrxL9tr9n3xN8VvB2m/E/4OzLZ/En4f3Z1XwZfAYM7AfvrF+m6OdBsKkgbtuTtLZ639mP9oLwx+018HdM+KnhyFrWWcNb6xpUp/e6bfR/LPbSA4IKt0yASpVsDdXl4GUsJVeBqPZXg31h29YbPvHlfc8bLZzwNd5dVd+VXpt/ah/LfrKnpF9XHkl3PQKKKK9Y9sKKKKACiiigAooooAKKKKACqmv69o3hbQr3xN4i1KGy0/TrSS5vry4fbHBDGpZ3YnooUEk+gq3Xyp+29r2s/tMfF3w//wAE7vh1qc0Nvq8aa18WdUtHIbT9CjcFbXcPuy3LhVA6hdpIKua7cvwf13EqDfLFXcpfyxWsn92iXVtLqcOY436jhXUiuabajGP80npFffq30ipPoH7EWg6z+0z8XvEH/BRD4iabNDbatHJonwl0u7TDafoUbkNd7T92W5cM2eoXcASjivquqmgaDo3hXQrLwx4c0yGy0/TrSO1sbO3TbHBDGoVEUdgFAAHoKt0ZhjPruJc0uWKtGMf5YrSK+7VvrJt9Qy7BfUcKqcnzTbcpS/mk9ZP79EukVFdAoooriO4KKKKAPE/2xZZPHD+DP2c7F2L+NvEcZ1RUPI021xPcHjp0THrg17VFFHBEsMMaoiKFRVGAAOgFeKfDP/i6n7XvjP4lSfvNO8FWEXhnR26qblj5t2w9GVv3ZPowr22vluHf9uxmNzR7VKns4f8AXuhemreUqntZeejPp+IP9iwmDyxb04e0n/18rWm7+cafso+WoUUUV9SfMBRRRQAUUUUAFFFFABXzP+z/AP8AF9P28vij8fJT52k+A7SHwJ4ZkPK+eh8/UGHYMspVMjkq+K9l/aJ+Len/AAH+Bnir4v6iUK6Bos91BHIeJZwuIY/+BylE/wCBVxv7Afwk1D4O/sp+FtG8Qh21zV7Ztb8QzTD95Je3jGd9/qyh1jP/AFzry8T/ALRmNGh0heo/l7sP/JnJ/I8XGf7Vm1DD9IXqy+XuU1/4E5S/7dPZaKKK9Q9oKKKKACiiigArxn9g/wD5Ihrn/ZZviP8A+prrdezV4z+wf/yRDXP+yzfEf/1NdboA9mooooAKKKKACiiigAooooAKKKKACiiigAooooAK8r/bo+K+v/Af9iT4x/HHwpceVqngz4V+Idd02UDOy4tNNuLiNvwaMGvVK4P9qX4ffC/4tfsx/Eb4VfG/xX/YPgvxN4D1fSfF+uf2jFZ/2dpdzZSw3Vz58wMcHlwvI/mSAom3cwIBoA8i/wCCQH7Lfwr/AGU/+CePwr8KfDjwxa2t9rngjS9c8XawsI+1a3q93ax3F1d3Mv35naWV9pcsVQKgO1QK8s/4Kx/DLwV8L/2mP2Vf25/BGg2umfEGx/aK8PeBtT16zhWOfVNA13ztPubK4ZQDOitJFJHv3eWVfbjeTXzRpX/BO/8A4I0aFpdtomif8HE3xZs7Kzt0gs7O1/bK0aOKCJFCpGiKgCqqgAADAAAFdH8I/wDgnb/wR5vPjv8ADnxFYf8ABcL4g/EnXfDPxD0XXfCPg7xL+1No+tW2o6zaXsU1lF9j8stOzTKqBI8SNvKqQWoA/WCvj3/gtP8A8kB+FP8A2dF8NP8A1JbOvsKvBf2sf+CZ37HX7b/i3TfG37S3gfxLrd7pFvaxadHpvxN8QaRawm2uJLiCYW2nX8EBnSWRnWcoZRhBvwiBQDwv9tS2+LnjL/grV8J/Cn7HPiPQPDPxZ0T4K+IdS13xJ49sZNQ0OXwtPqVhC1mLCF4p7i7N7FBIskVzbiKON95lEioN/wD4IvSX+leEPjx4B+IKxXHxK0T9ojXD8V9c025V9L1nW7i0sbgXVggjQ21v9kktI/sz7pInicPJKxMj+qeM/wDgmR+xZ8QvAfg74f8AjD4YatexeAI7mPwfrrePdbTXtMjuGLTomsJeDUGSQn5la4ZSFUEYRQPQ/wBnr9mz4G/sp/DpPhR+z78ObLw1oQvZr2a1tXkkkuruZt0tzcTSs8txO5A3Syu7tgZY4FAHmHwC1L4r6n+378X5Piz4L8PaJcx/CvwOmmReHfE8+qJcWY1XxdsmleaytDDKTuBiVZFUAESNkgfQ9eM+B/8AlIX8UP8AsjPgP/07eL69moAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCtrGj6V4h0i60DXdOhvLG+tnt7y0uYw8c8TqVdGU8MpUkEHqDXyn+zHrGq/sQftBSfsKePtQmk8E+JHn1P4K63eSFhGm7fcaM7nq8bNujzyQ3XLoo+ta8t/a/8A2ZtG/an+Dlz4Ek1JtL12xuE1Lwh4hhJWbSNUh+aC4Rl5Az8rY5KscYOCPUy3E0Yc2GxD/dVLJv8AlkvhmvOLeq6xcl2PKzPC1p8uKwy/fU7tLbmi/ig/KSWj6TUX3PUqK8T/AGH/ANpnWfj58Pr7wr8UdNXSviT4Gvf7H8f6IwCmO7TIW6QDgwzqpdSPlzuAJCgn2yuPFYWtg8RKjVXvR+59mn1TVmn1TTOzCYqjjcNGvSfuyXzXRpro00010aaCiiiuc6QooooAKKKKACiiigAooooA8h/aU+F3ilNRsP2hvg3bD/hMvC8Z8yzXga1p+cy2bgfeOMlO4PTkqR3fwm+KPhb4y+ArD4heELkvaX0WWif/AFlvKOHicdmVsg/mMgg10deA+Oba4/ZF+LUnxe0WB/8AhX3i69RPGVjEpK6RfOdqX6KOiOTh8dz3JQD4/ME+GsxlmcP92qte3XSEtIxrpdto1v7vLV3hNn12Aa4jy+OWz/3mkn7B/wA8dXKg/PeVH+9zU9pxR79RTLa5t7y3ju7SdJYpUDxSxsGV1IyCCOCCO9Pr69NNXR8k007MKKKKYgr5U+K0cn7CX7TqftEaWjRfC/4mX8Vl8RbZB+60XVmOINUwOFSQkrKeBkljuZkA+q6xfiN8PvCXxX8Cat8N/HekpfaRrVi9rf2z/wASMMZB/hYHDKw5VgCORXFjsLLE0k6btUi+aL7Nd/KSvGS7PukedmWCnjKCdJ8tWD5oPtJdH/dkrxkuqfdI2Y5I5Y1licMrAFWU5BB7ilr5s/Ym+IXi34XeK9X/AGEPjXqr3HiDwZbC48Gazc8HXvD5O2CQeskPEbgdAAOdjNX0nV4PFRxlBVErPZp7xktGn6P71ZrRmmAxsMfhlVSs9VKL3jJaSi/NP71ZrRoKKKK6jtCiiigAooooAKKKKAOF/aU+PnhD9mT4Ka98afGrbrXR7Qtb2aNiS9uWO2G3T/aeQqvsCSeAa89/YD+Afi/4a/D/AFT4yfGpPN+JfxOvxrnjKZ0w1puH+j2C5+6kEZ27f4WZgCQFrhdS/wCM8f23U0Nf9J+FnwJ1MS33eDXPFePlj9HS0UnPo+QQVkFfW1e1if8AhOwCwq/iVLSn5R3hD/2+S7uCex4WF/4U8weLf8OleNPzltOf4ezi+ym1uFFFFeKe6FFFFABWB8U/Hdh8MPhxrfxB1LaYtI0yW52MceY6qdifVm2qPc1v18Z/8FRfjv4r0bU9P+A2jGGLTL7TYdS1Z9oZ7gidxHCc/dUNCHP97I7DB+T444lo8JcMYjMZ35kuWFlf95O6h8k9X5R8z6rgvhyrxVxJQy+FuVvmnd29yNnP5taLzfke/fsfeA7/AMCfATRzru5tW1zfrOsyuMO9xdHzTu/2gpRT/u16dXDfs1fETxB8V/gX4c+IHinR0sb/AFGyZri3jjKIdkjxh1U9FdVDgejiu5r0uHIYOnw/hI4Rt0vZQ5W1ZtOKd2nqm7uTv1k/V+bxDPF1M+xcsUkqntJ8yTuk1Jqya0aVklbol6Iooor2jxwooooAKKKKACiiigD5n/b5J+L3j74VfsdWhMkPjLxWNW8UxLyP7H04CeVH9BI+0KT/ABR4r6YAAGAMAdAK+Z/2bP8Ai+X7b3xY/aMm/faX4RWHwF4WlPK7oCJr9h2z55UBh1ViK+mK8vLf3062Kf25WX+GF4r73zs8XKf9oqV8a/8Al5K0f8FO8F98ueXzCiiivUPaCiiigAooooAK8Z/YP/5Ihrn/AGWb4j/+prrdezV4z+wf/wAkQ1z/ALLN8R//AFNdboA9mooooAKKKKACiiigAooooAKKKKACiiigAooooAK83/bJ8cfDT4ZfshfFX4k/GfwKPFHg7w98N9c1PxZ4ZMMcg1fTINPnlurPZIQj+bCjx7WIU78HjNekV5F/wUD+Ffjn46/sF/G74I/DDSF1DxL4y+EXiXQ/D1g9zHCLm+u9LubeCIySMqRhpJEXc7BRnJIAJoA+Wfif+xr/AMEMfgv+xzpn7bnxJ/4Js/Da08J6lp3h+6+zWnw8sp7uH+17mztbVCgABIlvYQ5DYADEZxz7x4I/4JFf8Ev/AIa+NNI+I3w//YJ+Feja9oGqW+paJq+neDrWK4sbuCRZYZ4nVMo6SKrKw5BUGvz3/aM0X/gv9+0L/wAE/NP/AGCrz/gkD4a0u00+w8LWw8SxfHvRZZHGi3+n3it5BkUDzTYBCN/yiUn5tuD9UfCL9sf/AILpeKPix4X8NfF3/gjb4X8L+E9R8RWVr4n8TW/x90q8k0jTpJ0S5u1t0+adooi8gjX5nKbRyaAPuuiiigAooooA8Z8D/wDKQv4of9kZ8B/+nbxfXs1eM+B/+UhfxQ/7Iz4D/wDTt4vr2agAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD5a/bZ8AeLvgJ8RtO/wCCh3wO0WW71Dw7aCy+J3h60GDr/h/ILyY6Ge3ADqx/hQZO2Pafoz4efEDwj8VfA2lfEjwFrMWoaNrdjHd6deQniSJxkZHVSOhU8ggg4INa80MNxC9vcRLJHIpV0dchgeCCD1FfIvwmmm/4J6ftPj9m/WpWj+EfxP1KW7+Gt5I37rQNYc7ptJJP3Y5Sd0Q9SANzGRh7lP8A4VcD7J/xqS93vOmtXHzlDWUe8OaP2UeDU/4SMf7VfwazXN2hUeil5RnpGXafLL7TPryiiivDPeCiiigAooooAKKKKACiiigAqn4g8P6N4r0O78NeItOivLC/t3gu7WZcrLGwwyn8DVyipnCFSDhNXTVmnqmno011TTsyoTnTmpwdmndNaNNapp90zwr4G+INZ/Z9+Ig/ZW+IWoyz6Xcq8/w41u5b/j4tgctYu3TzYs/L6r6AoK91rivj18F9J+OHgOTwzc3bWOpWsq3eg6vDkS6feJzHKpHOM8EDqCehwRkfs2/GfV/iLo994H+Itoth438LTC08S6fwBIcfJdR+scg+YEcAnjgqT8llM55Bj1k1d3pSu8PJ9lrKg2/tU1rTu7ypaaypO/1WaQhnuBeb0VarGyxEV3eirJL7NR6VLaRq66RqK3plFFFfXnyYUUUUAeG/tu/ALxZ8R/DGlfGT4KsLb4l/Du6bU/Cdwo/4/VA/f6fJ03RzICu0kfNgZAZs9v8As1/H3wn+0v8AB7Sfiz4TVoReRmPUdOlP73T7xPlmtpBwQyNnqBlSrYwwru6+A/2qf2mNJ/4Jjfti6hrfgDw//bmkfEvQ11nxN4L+2G0S0vxM8S38MvluoMuyXem35mUkkfJjw8wr0snr/XZu1OVoz9dozS6v7MratWf2T5vNMTQyDEf2jUdqM2o1PJ7Qml1enJJLVx5Xryn35RXG/s/fG7wn+0d8HNC+NXgiK4j03XbVpIobpQJIXSR4pY2xwSskbrkcHbkcGuyr2aVSnWpxqQd4tJp909UfQUa1LEUY1abvGSTTXVNXT+4KKKKs0CiiigArwv8Ab1/aG8T/AAZ+F9l4D+EUX2r4kfEPUBoPgSyQ/MlxJgSXjddscCNvLEFQxTdwSa9t1XVNN0PS7nW9Zv4rWzs7d57u6nkCRwxIpZnZjwFABJJ6AV8sfsa6VqX7WPx313/goT43sJU0ZUm0D4OaddIVNtpUbss+obT92S4fcAeGC715Uqa9bK6NKLljK6vTpWdn9qb+CHo2ry/uxfc8jNa9WShgqDtUq3V19mC+Ofqk+WP9+S7M9s/Za/Z68MfsufA7Q/g54Zl+0HT4DJqmpOP3moXsh3T3Lk8ku5JGScKFXOFFehUUV51etVxNaVWo7yk22+7Z6VChSw1CNGkrRikkuyWiCiiisjUKKKKAML4mfEPw58KPAeqfEPxZc+XY6XatNLgjdIeixrnqzMQoHqwry39n34EWXjDQ7/4yftB+CtM1bxL4zukv5LLV7CO4TS7UDFtbIsqnYVQgngHJAPK5qp4p/wCMpP2ho/AEP73wP8OrtLnxAw5j1PV+fKtfRki5LD1ypHKmveq+Nw9KlxNm8sVWipYbDuUKaaTjOp8NWpZppqGtKndNX9rJdGfX16tXhvKY4WlJxxNdRnUabUoU/ip07pppz0qzs07eyi+qGwww20KW9vCsccahY40UBVUDAAA6CnUUV9kkkrI+Qbbd2FFFFABRRRQAUUUUAFfPP/BTf9pj4lfsq/syv8QPhRaw/wBsX+uW+lxX88AlXT1kjlc3GxgVYgxBAGBXMgJBxg/Q1fLHxSsbL9s39tfT/gfeWcWofD/4QRx6x4yt5oxJb6lrcyEWlm6nKuscZZ2ByDmRGHSvLzipWWCdKjLlqVPdi1um+vpFJtvt52PFz6rXWXSoYeTjVqtQg1upPd+kYqUm+iWmrRw//BDj4u+LfHfwQ8U+BNf8Polr4d1xZ7XXFRg2oS3hmlmWRjw8iFFJbrtlQEcAn7frL8H+CPBfw80OPwx4A8IaXoemxMzRado+nx20CEnJIjjUKCT14rUrTKsHVy/LqeGqT53FWvt1f5ba69zXJMBWyvKqWEq1OeUFbmta+r/K9tde+oUUUV6B6oUUUUAFFFFABXjP7B//ACRDXP8Ass3xH/8AU11uvZq8Z/YP/wCSIa5/2Wb4j/8Aqa63QB7NRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRXy1+3D+3z8e/2PPip4I0jTf2LH8T/D3xV428N+GdQ+I8/xEtLBbC81fUksVWKwEM1xcNEZEkbcIkYNgSZBIAPqWivJf2hviF+2l4O8QWFn+zF+y94F8eaZNZl9SvvFfxbuPDsttPvIEaRRaPfCVduDvLocnG3jJ5n/AIJpftoeNf2+f2aD+0X4v+Clh4IguvFWraXodtpXi5tattVs7G5a0/tCG4eztG8qWaKcIDECURXz8+1QDa8D/wDKQv4of9kZ8B/+nbxfXqviG+vbZbSx02RY5r67ECTMm4RgI8jNjudqHHuRXlXgf/lIX8UP+yM+A/8A07eL69S8Qf8AIW0P/sKv/wCklxQAg8P6vjnxzqmfaG0/+MUv/CP6t/0POq/9+bT/AOMVqUUAZf8Awj+rf9Dzqv8A35tP/jFH/CP6t/0POq/9+bT/AOMVqUUAZf8Awj+rf9Dzqv8A35tP/jFH/CP6t/0POq/9+bT/AOMVqUUAZf8Awj+rf9Dzqv8A35tP/jFH/CP6t/0POq/9+bT/AOMVqVz3xa+Kfgf4G/C7xF8Z/ibqs1h4c8KaLc6tr1/b6fPdvbWdvE0s0oht0eWTaisxVEZsA4BoAu/8I/q3/Q86r/35tP8A4xR/wj+rf9Dzqv8A35tP/jFcve/tO/AbTv2aH/bEvPiRZp8NU8Gf8JYfFYilMJ0c2v2oXQQJ5hBhwwQJvOQoXccV8of8FLP26/8AgoD8HP2Xrv8Abg/YE8H/AAa1j4S6X8LIfGV3rnxRGuRarfCQPKsFtpsKQMgNubd83EsTBpGVkBTBAPtf/hH9W/6HnVf+/Np/8Yo/4R/Vv+h51X/vzaf/ABisr4G+N9W+JvwT8HfEjXre3hvvEPhbT9SvYrRGWJJZ7aOV1QMzEKGcgAknGMk9ap/tE6n+0DpHwb1m/wD2WfCvhfWvHqrAvh/TvGmqT2elyM08aytcTQRySKqQmVwEUlmRV43ZAB0P/CP6t/0POq/9+bT/AOMUh0DWQMx+ONSLDoJILUr+IEIP6ivlH/glh+2X+2H+0n8R/j58FP20dA+Gln4m+Dfjqy0GOb4X22oJY3Cz2K3TEvfSvJKRvChtkWcH5K+w6AKPhzUbnVNJS5vFUTJLLDNsGFLxyNGxA7AlSfxq9WX4P/5BM3/YVvv/AErlrUoAKKKKACuA/ab/AGePBf7UfwZ1b4PeNg0Ud9GJNO1KFf32nXicw3UR4IdG54I3KWU8Ma7+itaNarh60atN2lFpp9mjKvQpYmjKlVV4yTTT6pngH7Cn7Q/jPx9o2s/s9/H7bbfFP4bTrp/ieNj/AMhW3x/o+pxZxvSZNpJH8RyQodRXv9fnh/wXP0P4pfDW98C/tM/Aka3oOpQWt/o3ijxf4ZvZrW4itnMD2sEskLAiMt9oIJ4BwM8rWn/wTz/4KWzeDvgro/g79vfWfE+ialfXjnwp428U6FcJZavYFU8vdeFSHlVxMDI+FKBCXJzX1WL4eq4/LY5tgkmpvWnH4oyV+blV9Y3XMklzRjLZpJnyOE4jpZfmksnxzadNaVZaRlF25eZtaSs+Vyb5ZSjum2j78oqh4a8U+GfGmiQeJfB3iKx1bTbpN9rqGm3aTwTL6q6Eqw+hq/XyLjKLs1Zn2UZRkk07phRRRSGFFFFABRRRQAUUUUAFePftJfDTxVpmsWP7SXwas9/izw1CVv8ATo+Brmm5zLauB95gMsh5ORgAnbj2GivNzfK6GcYGWHqNxejjJfFCcXeM4vpKL1XRq8XeMmn6OVZnXynGxxFNKS1Uov4ZwkrShJdYyWj6p2krOKa5/wCFvxL8LfF/wJp/xC8HXnm2OoQ7lVsb4XHDxOOzq2QR7cZGDXQV4B4shl/Y++Lb/EnTImX4ceMr9U8T2sYymiai5wt6oH3YpDgPjof+ALXvsM0NxClxbyrJG6hkdGyGB5BBHUVxZFmlfGQnhcYlHE0Wo1Etnf4akP7lRLmW/LLng9Ya9md5ZQwk4YnCNyw1a7pt7q3xU5f36bdn/MuWa0lo6iiivfPCCvEf2tP+Cf8A8Af2yr/S9b+KUer2Wp6REYLfVNBvI4Z5ICxbyH8yORWQMWYfLkFmwRk59uorDE4XDYyi6VeClF9Hsc2MwWEzDDuhiYKcHumrrTY+Urj9lT42fsVSnxl+wvqs+u+GEAfXPhH4j1FnjucAb5rC4fJgnbGSp+ViT97Cx16/+zh+1p8KP2mNMuYvCV1c6Z4g0tvL8QeENbh+z6lpcoOGWWFuSoPG9cr2JByo9Orx39o/9jPwF8eNTtviLoGsXng34g6UM6J478Pny7uEgYEcwBAuYuxR/wCEkAqCc+f9Tr5f72C1h1pt6f8Abjfwv+6/cf8Ad3PK+oYnK/ey7WHWk3Zf9w278j/uu8H/AHHqexUV8z+A/wBsf4g/A7xZZ/BT9vjQ7XQb+6l8jQPiTpykaFrpHTzHwBaTkclWwvU/INufpaKWKeJZoZFdHUMjqchgehB7iu3C4yhi4vk0a3i9JRfZrp5PVPdNo9HBZhhsfFum2pR0lFq0ovtKL1Xk9U902h1FFeJfte/tdL8BINM+GXww8N/8JZ8UvFxMHg3whbtksxyDd3JBHlW0eCzMSN21gCAHdPSwuFr4yuqNJXk/kkurb2SS1beiRpi8XQwVB1qztFfNtvRJJatt6JLVv8PFv2x/2pvh3+1b8TNB/wCCc/wM+LFp9p8Va89p8R9ZtZSi2OnW6+bPZQysAs0820x4jLgbWRvvHH2N4U8LeH/A/hjTvBnhPSorHS9JsorPTrKBcJBBGgREUegUAfhX5vfsrf8ABDj4yfCb9pHwp8Xfib8XvDs+j+GtUtNYMOjPcNeXF5CySiEiSJUWPzVwX3kso+6pbj9Ma9/iJZVhoUMJl1b2lOKbk7bzb1b0V9Eklb3Vpd3bPnuGnm+JnXxmZ0PZVJNRir7QS0S1dlzNtu/vN3srJBRRRXzB9UFFFFABXmv7T3xd1f4aeCYNB8Cwi58X+KboaZ4WsxjPnvw059EiU7iTwDtB4NeiajqNhpGnz6tql3Hb21rC01xPK21I41BLMxPQAAkn2rxH9njTr/46fEvUf2sfFVpIlgVk0z4e2NwuDBYqxWS72no8zZ56hdw5BWvmuIcZiZKnleDly18Rdcy3p01b2lX1SfLDvUnH+Vn0eQYTDxdTM8ZHmo0LPle1So7+zp+ja5p9qcJfzI9F+BXwi0n4I/DSw8B6bMbiaIGbU79877y7fmWZieSS3TOSFCjtXX0UV7mDweGy/CU8Nh48sIJRil0SVl/wXu223q2eJjMXiMfip4nES5pzblJvq27v/htkkktEgooorpOcKKKKACiiigAooooA89/am+POk/s1/ArX/i3qMIuLiwtfL0iw5Jvb6Q7LeAAcndIVzjkKGPasH9iD4C6t8BvgZa2njeZrnxh4lu5de8bX8uDJPqdyd8isR12DbHxwShI+9Xn3jD/jLr9uzT/h7H+/8DfBBo9W17vFfeI5VP2WA9m8hMucdG3qw5FfUNeThv8AbMfPEP4YXhD1+3L77QXlGR4mE/4UMzni38FO9OHm/wDl5L70oJ9oy7hRRRXrHthRRRQAUUUUAFFFFABXjP7B/wDyRDXP+yzfEf8A9TXW69mrxn9g/wD5Ihrn/ZZviP8A+prrdAHs1FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFfnp/wAF7v2xf2Wvg/4O+FvwZ+KHx58NaF4ri+OXw98VyaBqWpLHdLolv4khafUCh58hBbXBZ+g8l/Sv0LooA+P/APgox+25oF//AME0dQ+Jn7GvxD0zxPrfxkntvAnwd1jRLwSQ32s6vcnTopoZF4JgzcXBPQC0b0r6I/Zo+Angv9lr9nrwT+zh8O4NmieB/C9lounEoFaVLeFY/NfHV3Kl2PUsxJ613FFAHzx8AvBfiTwT+378X7XxL8XPEPi+S8+Ffge5t7nxFbadE9jE2q+LgLWIWFpbKYlwSDIry5Y7pGGAPc/EH/IW0P8A7Cr/APpJcV5b4H/5SF/FD/sjPgP/ANO3i+vUvEH/ACFtD/7Cr/8ApJcUAcN+0b+zP/w0V/Y3/GQPxO8C/wBj/aP+Sc+K/wCy/t3m+V/x8fu383Z5XydNvmSdd3HmP/Ds/wD6yBftN/8Ah1v/ALmr6bor0aGbZjhqSp0qlorpywf5wb/E83EZPluKrOrVp3k93zTXlsqkV+CPmT/h2f8A9ZAv2m//AA63/wBzUf8ADs//AKyBftN/+HW/+5q+m6K2/t3Nv+fv/ktP/wCVGH+r+T/8+v8Ayap/8tPmT/h2f/1kC/ab/wDDrf8A3NXT/Bz9hv8A4U98SNO+I3/DYPx08U/2d53/ABIfGXxB+3abdeZC8X76DyV37d+9eRh0Vu2K90oqKmdZnVpuE6l01Z+7DZ+lNP7mvU0p5HlVGopwp2ad171TdetRr70/QKra1o2k+I9Hu/D2vadDeWN/bSW97aXEYaOeJ1KujKeCpUkEdwas0V5Z6p+GGn634s1b4aaZ/wAGwt/qd9Jr1l+0g/h7Up3kb7RJ8I7cr4jS8aX+F3tmis1GcEDZk5wfvr/gvL8TPg78P/8Agk/8cPhZrPxB8NaJq2pfCq+i8P8Ahy61a3trm6QKEVbe3Zg0gGNoCKemO1fVEfwD+BUPxhk/aHi+C3hJfiBLpn9my+OV8OWo1h7Pj/Rje+X55i4H7vft4HHFYXxu/Yy/Y+/aZ1qz8SftIfso/DX4g6jp1qbbT7/xv4F0/Vp7WAsXMUb3ULsibiW2qQMknFAGF+w58Zvg/wCPf2TfBE/gT4q+G9bTQPAGjJrraPrlvdf2cwsI8rP5bt5R+R+Gwflb0Ndt4W/aF+A/jf4P2/7QnhL4zeF9Q8B3Vu1xb+MrbXYG0uSJZDE0gud/lbRIpTO7G4EdaofBn9k79lj9nHStW0L9nn9mn4f+A7HXtn9u2fgzwbY6XFqOxWVPPS2iQTbVdwN4OA7AdTVqL9mn9nKD4KH9mqH4AeCU+HJtTbHwAvhWzGieSZTKYvsPl+RsMhLldmNx3YzzQB8J/wDBJv8AaH+AFz/wUL/bUs7f45eDpJvFXxs0c+GIk8TWhbWB/Y8CZtQJM3Hz/L+73fNx1r9Iq8T8E/8ABNT/AIJzfDXxdpvxA+HP7AXwT0DXtGvI7vSNb0T4VaRaXdjcIdyTQzRW6vE6kAhlIIIyDXtlAGX4P/5BM3/YVvv/AErlrUrL8H/8gmb/ALCt9/6Vy1qUAFFFFABRRRQAVR8R+GfDfjHRbjw34u8P2WqaddJsurDUbRJ4Zl9GRwVYexFXqKabi7p2YnGMlZq6PmXxN/wTM8C+FdbuPHX7H3xW8SfBvX5n8yWPw3cm40i6ft5+nzExuOmFUqo/u1R/4aJ/b2/ZoP2f9pj9nSD4keHYPv8Ajb4TZe7RB/HPpsuHLY5YxlUXHevqiivWWcVqq5cZBVl/e+NelRWl9/MvI8eWS0KTc8FN0X/d+B+tN3h9yg/M8t+Af7aP7M/7S6fZ/hJ8VtPvNSUH7RoN4xtdRgZfvBraYLJ8pyCwBXI6mvUq8o+Pn7Ef7Mf7Sj/2j8UPhbZSawhDW/iPTM2epQuv3WFzCVdtp5AcsvtXlv8Awof/AIKC/szfvv2ePj/a/FTw5B93wd8VDt1FEH8MOpR4Lv0A83ai46Gn9VyvF/7vV9nL+Wpt8qkVb/wKMfUn63m2D/3mj7SP81Lf505O/wD4BKXofVNFfNHhP/gpr8M9E16DwF+1l8OfEfwa8RzNsjj8XWpfTLl+/kahGPKkQf32CLx1r6M0LX9C8UaRBr/hnWrTUbC6jD2t7YXKzQzKf4ldCVYe4NceLy/GYJr20Gk9nvF+kleL+TO7CZjgsen7Com1utpL1i7SXzXzLdFFFcZ2hRRRQAUUUUAUfE3hrQvGXh698K+JtNjvNP1C2aC7tpRlZEYYI9vqOQeRXjXwG8S658CvH5/ZR+JOpST2pief4d63cn/j+shybNm/56xDgDuo6AbM+51w/wAf/gtp/wAbvAraGt82n6xYTreeHdZiyJLC9TlJARztJ4YdwfUAj5zPcuxUpwzLAL/aaKdleyq03rOlJ/3rc1Nv4Kii9pTPockzDDRhPLsc/wDZ61rvd05rSNWK8r8s0vjpuS3jA7iivNv2b/jTqHxP0C88L+O7Ead408MTiy8UaYcDEo+7cIO8UgG4EcdQMjBPpNerluY4XNsDDF4d3hJddGmtHGS3UotOMovVSTXr5eY5ficrxs8LiFaUX01TT1UovZxkmpRa0aafoUUUV3HEFFFFAGP488AeCfih4UvPA3xD8L2Ws6Rfx7LvT7+ASRyDscHoQeQwwQQCCCM180y/Dj9pH9gKRtV+BcepfEv4SxMXuvAV3OZdY8PxdS2nytzcRL/zxbngAclpK+rq8b/a7/a40v8AZv0bTvCvhLw7J4p+IviuU2vgnwVZHM19OePOlx/q7dOrucDAIBHJXF5RLNcTGNC6q/ZkrJpbu99HBbyUvdtd6bnjZvh8EqX1upN05wWk4/Er7Rt9tN2XI07t6Weq4j4kf8FN/hDc/DPSLn9mc/8ACd+PvF87WPhPwRbgpdR3YHztexkhraKLO52bAYD5W25deo/ZB/ZFu/gtPqfxm+M/iNfFfxZ8XASeKvFEi5W3U4K2NoCB5VtHhQAAN+0EgAIq+S+C/wDgmd8V9AsG/aHtf2gbnSvj7qN9Nqmq69aQqdHkeYKW01rYLhrYbQu/G4nL7ThVHpnwU/bZuJPG8P7P37Wfg5fh98RG+WyWaXOleIBnAlsbgnadxx+6Y7gSFBZgQN55xLLaby6pZOTs60b8lXXSKbScF/cl8cveUpLlivHwVfEyxtOtnMeSWnsv+fabVrvV8tZ9pO0U+WnJvmb+gaKKKR9iFFFFABRRXKfGz4s6H8E/htqXxC1xfNFpHts7NT893ctxFCvfLNjpnAyegrnxeLw+Aws8TiJKMIJyk3skldv+t9EtWjowmFxGOxUMPQi5Tm1GKW7bdkv6829Ezzn9pHVtT+M3j7TP2SvB17JFFfRrqHjy/t2wbPTFYEQZHR5mwMehGQVY17TpGkaZoGk22haLZR21nZW6QWtvEuFijRQqqB2AAArzj9l34T654C8JXfjT4hsJvGXi+6/tLxLcMOY3Yfu7YeiRKdoHQEtjjFen14PD2ExFR1M1xkXGtiLWi96dJX9nT8nZ89TvUm19hHuZ/isPTVPK8JJSo0L3ktqlV29pU81dclP/AKdwT+2wooor6Y+bCiiigAooooAKKKKACvOP2sfj5Yfs1fAfXfipLbi5v7eAW2g6ftLNe6hKdlvCFHLZcgkDnarHtXo9fL2u5/a7/bxtfDC/v/AvwLZL7Uu8V/4mlU+TH6N9mQFuOVkDKRhq8/Ma9SlQUKX8Sb5Y+Te8vSKvJ+iXU8vNsTVoYZU6D/e1HyQ8m95ekI3k/RLqej/sU/AO/wD2fPgRY6B4ruDdeKtbuJda8aag7BnutUuTvmLMPvbfljB7iPPc161RRXVh6FPC0I0ae0VZf13erfm2dmFw1LB4aFCkvdikl8u/m9W31bbCiiitjoCiiigAooooAKKKKACvGf2D/wDkiGuf9lm+I/8A6mut17NXjP7B/wDyRDXP+yzfEf8A9TXW6APZqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDxnwP/AMpC/ih/2RnwH/6dvF9epeIP+Qtof/YVf/0kuK8t8D/8pC/ih/2RnwH/AOnbxfXqXiD/AJC2h/8AYVf/ANJLigDUorjPi7+0J8IPgP8A2f8A8LW8Xf2V/avm/YP+JfcT+b5Wzf8A6mN9uPMTrjOeM4NcX/w8I/ZB/wCiu/8AlA1D/wCR68LGcUcM5diZYfF42lTqRteMqkIyV1dXTaaunf0PbwfDPEeYYeOIwuDq1KctpRpylF2dnZpNOzVvU9norxj/AIeEfsg/9Fd/8oGof/I9H/Dwj9kH/orv/lA1D/5Hrl/124N/6GVD/wAG0/8A5I6v9TeL/wDoX1//AAVP/wCRPZ6K8Y/4eEfsg/8ARXf/ACgah/8AI9bXw9/bG/Zw+KvjCz8BeAviN9v1a/8AM+yWn9kXkW/ZG0jfNJCqjCIx5I6Y64Fa0OL+E8TWjRo4+jKcmkkqsG23okkndtvRIyrcJ8U4ajKrVwNaMIptt05pJLVttqySW7PTaKK5X46Xvxd034LeLdS+ANlo9z45tvDl7N4PtfEEEktjcaksDtbRXCxSxOYmlCK211IDEg8V9EfPnVUV8Oal/wAFgrRf+CI8H/BUTR/CtjN4svvBsUFj4QMMpifxlJcDTf7M8oOJmjXU8oUDCTykJyD8w8w/4Lm/sJ/Db46f8EwfHH7XX7XXhL+0vjF4J+BKqBoXiXVLXQtN1WJGmmmttPF20L4nmlCvP5z7FjBY7QaAP0yorz39kj/k1L4Y/wDZPdF/9IYaT9p39l/4V/te/DA/Bv40jW5fDc+ow3Wo6fofiO70tr9YskW801pJHK0LE5aMOA20A8cUAeh0V+Vmrfs1fAL9jj/gtL8AfgX/AMEr9CvPCmr3Wm6xqf7R3hDw5rV3NoqeF/soWzudTglleOK6a5YCBgBIzMpbKlCf1ToAy/B//IJm/wCwrff+lctalZfg/wD5BM3/AGFb7/0rlrUoAKKKKACiiigAooooAKKKKACiiigDN8WeDvCPj3QZ/C3jnwvp2s6ZdLtudO1WyS4glHoySAqfxFfOmu/8E0fD3gLV5/Gf7Fvxp8TfB/WJpDLLp+lXBvtEupPWawuCUPoNpCqOi19O0V24XMcbgk1Rm0nut4v1i7xfzXzOHF5bgcc060E5LaSupL0kmpL5O3kfK/8Aw1B+2/8As1/6L+1d+zMPGmgwcP48+EZa5ZUH8c+nSkSrxy7qQg5wDXr3wF/a/wD2bv2mLTzfg18WdL1W6VS0+kPIYL6DHXfbShZVAORu27eOCa9KryD49fsJfsv/ALRl5/b/AI++Glvba+jB7fxVoMhsNThkH3XE8OGcjsJN4HpXZ9ZyrGfx6TpS/mp6x+dOT/8ASJL0OP6rm+C/3eqqsf5amkvlUiv/AEuD9T1+ivlb/hT/APwUW/Zj/e/BD40af8ZPDUH3fC3xIYW2sJGP4IdRTCyuePmmwo7LWt4J/wCCm/wdg8Qw/D39prwf4g+DniiU7VsfHNmY7G4bu0F8o8mSMf322A9qmWTYipFzwklWj/c+JesHaa+SkvMcc7w1OShjIujJ/wA/wv0qK8H83F+R9J0VX0rVtK13TYdZ0PU7e8s7mMSW91aTLJHKh6MrKSGB9RVivJaadmewmmroKKKKQzxv9pD4c+KfDmv2f7TnwcsTJ4l8PQGPWdLj4GuaZ1kgYDrIoG5DyeMYJCgej/DT4jeFviz4H074geDb8XGn6lAJIicbo26NG47OrAqR6g1u18C/tEfG74ofsk/tJ+JfCfwSvX0bQ7+7ttTl0q4s45ra5mkhRpXiDoTGjMWUhCOUIyMAD834nzrC+HmIeb1FJ4XESUakIq7jVa92rFaL31Hlqq6u1CavLmUv0PhrJ8Vx9h1lVNpYmhFypzk7KVJP3qUnq/dcuam7OycoO0bNffVFeG6H+2s/9i2d54z/AGbfibp801rHJPNB4UaW13FQTscPkrnplQcYyKtD9vj9nS0OPEmq65ox7jVPDV2mPrtjavfhxtwnKClLGQhez9/mp766+0pw79/meHPgzimMnGOElO2nucs9u3JOf5fI9oory7Sv21P2WdYx9k+NOkpnp9q8yD/0ai4rnP2iv29fg98HPhwfEHw/1mx8c+I9QmFn4c8NeHdQjuJLq7fhPNaMnyIR1aR8ADgZJAPrYDOskzStGlhcXSnKTsrVaf61F9/RHk4/J85yyjKrisLVhGKu70qn6QfyXVmp+1z+1toX7NHh6w0bQ9Bl8T+PfE8xs/BHgqwObjUrk8b2xzHAhOXkPAHA5rE/ZE/ZJ134aazqP7Q/7Q+vQ+J/i74qiH9t6wBmDSLc8rp1kD/q4U4BIwXIyeMVR/Y1/ZmvfDmv3/7TX7QHjDT/ABb8W/E8AGo6haTrLa6DanldOsQCQkag4Zhy5zyRkt9E19VXxeGwuHeFwU1JS+Oovt/3Yv8A59p/ObV37vLE+Vw+DxOLxKxeOg48v8Om/sf3pLrUa+UE+Ve9zSCuR+NfwJ+FP7Q/gif4ffF3wfbavp0vzReaNsttJjAlhkHzROP7ykdwcgkHrqK8WpTp1qbhUScXunqmerVpUq9J06sVKL0aaumvNM+UF8T/ALS//BPpha/EB9W+KnwegOIfEcUfm6/4Zh7C6Qf8fcCj/loOVAJO0BUP0j8Nfif8P/jF4OtPiB8MfFtlrWj3ybre+sZdyk91YdUcdCjAMp4IBrdZVZSrAEEYIPevm74lfsYeMPhh4yu/jv8AsJ+JLXwl4iuX83XPBV4p/sHxFjkh4lwLaU84kTAyf4NzPXl+yxeW60b1KX8t7zj/AIW/iX92Tuvsyex4vscdlGtC9Wj/ACN3nBf3G376X8knzL7MnpE+kqK8W/Z1/bR8IfGPX5vhL8QvDl34E+JOnLjVPBOvMFlfAyZbWThbqIgEhl5wM424Y+016GHxNDF0vaUpXX5Pqmt011TSaPVwmMw2Oo+1oS5l+KfVNOzTXVNJrsFeC6Vj9qb9opvET/vvAvw0vTFpw6xaprYHzS+jJAMAH+9ggkMRXRftUfEvxHoujad8HfhjNnxj43nax0tkPNjb4/f3jY5UImcHrk5GdpFdt8KPhp4c+D/w90v4c+FYdtpplsIxIRhppDy8rf7TMSx9z6V8xjv+F/Oll61oYdxnW7SqfFSpeajpVqLypRe7R9pgf+EHJnj3pXrqUKXeNP4atXyctaVN+dWS2TOiooor64+UCiiigAooooAKKKKACiiqmv67o/hbQr3xN4h1GKz0/TrSS6vrudsJBDGpd3Y9gFBJ9hSbSV2JtRTb2R59+158foP2bPgNrPxJgt/tWrFFsfDWnBdzXupTnZbxKo5b5juIHO1GxVb9jH4A3H7OnwG0zwfr9z9q8SajLJq3jDUXfc93qlyd87s38W04jDd1jB6mvmnwB+1h8Hf+Cg37f3hHw/puq3Nt4V8Aaddar4b0vVrfy313W1OBOEBYbIYQZYwxDgox2gFgPuuvGwFejmmLnjKclKELwhb5Ocvm7RX91dmfPZXicPnOOqY+lJSpwvThbXs6kvm7RX92Lez1KKKK9o+iCiiigAooooAKKKKACiiigArxn9g//kiGuf8AZZviP/6mut17NXjP7B//ACRDXP8Ass3xH/8AU11ugD2aiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiivkL/got+1J+3h+yl8RPh74y+FGh/CO4+FXiD4leEfCevf8JDFqlx4hkl1bV47KdrdIZIbaFY45VZHdpSWzmPAGQD69or5U/b8/4KB6l+zl8UvCv7N/wy8YfDTwz4n8Q+Hr7xLr3jj4waybPw74T0K1nt7Y3VwFlha5mnurqGCGBZogSJGaRQgDexfsm+NfiX8Rfgrp/jX4ofE/4beNLrUJpZdO8U/CZZl0XUbPOI5YhNcXJDZDBts0i5HDdQADC8D/APKQv4of9kZ8B/8Ap28X16l4g/5C2h/9hV//AEkuK8t8D/8AKQv4of8AZGfAf/p28X16l4g/5C2h/wDYVf8A9JLigDUooooAKKKKACiiigAooooA/KrR/wDglj+2Ha/8FN4vhLc+ArQfsgab8fJ/jrYat/blp5jeIpNOXZpAsxL56QR6o0l0B5Xkle4bFe+/8FsrL9t74yfsr+N/2PP2Tf2FdT+JcPxI8B3enXPjC1+IWiaTBolzIxRY5LfULiKSf5QH3J8vzYzkV9sUUAfOP/BPr4g/td6j+zzH4I/aP/Ye1P4V6v4I8M6bpmh2upePtH1ceInhtDG7o2nzSLbAPEgxKQf3oIztNc78f/jp/wAFVLv/AIJuJ8SfgB+w7pth+0drkX2U/Di98eaXd23hlnmlQ3jXkk0Vre+XCscqxhwC8qg5COD9YUUAfnb/AMEuPCH7WP7Jj2vw78Vf8Eo/iJb614815L/4wfHfxj8XfCeoahrF++fM1C7jtb+Sdoo8sIrWEMIkO1QWLs36JUUUAZfg/wD5BM3/AGFb7/0rlrUrL8H/APIJm/7Ct9/6Vy1qUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABWT428BeB/iV4em8JfEPwfpmu6XcDE+n6vYx3EL+5SQEZ9+1a1FVGUoSUouzXVaEyhGcXGSun0eq+5ny/qv8AwTZh+GOpTeK/2H/jz4l+E+oSSGWTQopjqWg3L9T5llcEhSem4NhQflWq/wDw1t+2N+zd/on7YX7LsniDRYOJPiB8JC17AEH/AC0nsZMTQgDlnyF67VNfVFFess4qVly42CrLu9J/KcbS/wDAudHjvJadB82BqSovtHWHzpyvH/wHkZ578Cv2rv2d/wBpbTP7R+CfxZ0nXHWPfPYRT+XeQD1kt5AssY7ZZQD2Jr0KvGfjr+wH+y7+0Bqf/CVeKPh8ukeJUk8238XeFZzp2pwy9pPOhx5jDt5gcD0rzz/hXH/BST9mEeb8LPifpXxw8MQfd8PeOWGn67HGP4Ir9f3c7erzevC0/qeW4v8A3WtyS/lqWX3VF7r/AO3lD1F9dzTB6Yqjzx/npXf30376/wC3XP0PqmsnxB4B8C+LNQtdW8U+C9J1O6sW3WVzqGmxTSW5znKM6koc88YrwjwB/wAFNfgXfeI4vh1+0BomufCHxY/H9j/ECxNrBMehaG8/1MkeSMOxTd2FfRFhf2OqWUWpaZexXNvPGHguIJA6SKRkMrDgg+orzMfldailTxlHR6rmSlF21TTtKLtumm7b6M9PL81oYhupg62q0fK3GSvo01eMo32aaV9tSWggMNrDIPUGivK/2r/2rfBf7K/geDV9U0+41vxJrVx9i8H+ENMG691q9bAWKNQCQgLLvfBCgjgsyqxh8PWxdaNGlG8paJf106tvRK7bSQ8TiaGEoSrVpcsY6t/1u3skrttpJNsxP2yPjj8Ff2d/B1tceIPhpp/ivxZ4huPsXg3wbb6bFNea1eNgKiqVYrGCyl5MEKCAMsyqeN/ZY/4J/wCk6PpGp/E39qnQ9I1zxr4slFzf6LZW6xaT4fjP3bO0gjwgKjAaXlmI+8eWfa/ZN/ZS8aaR4yuv2sf2r9Qt9b+LGv2+yOKM7rPwrZHO3T7MZIUgEh5ASWJYAnLvJ9D1WZ5dkCoPCLD0qrfxzlTpyu19mDlBtQT3as5vXSNk88sx+fSrrGTr1aSX8Omqk48qf2pqM0nNraLuoLTWTk15DqP7Bv7KGov5zfCWG3kByslnqd3CVPsElA/Sqv8Awwx8KrP/AJFnxv450TH3f7K8Wzpt+m/dXtFFfIy4M4SlLmWBpJ94wUH98HB/ifXR4w4qjHl+u1Wu0puS+6amvwPF/wDhkzxlpn/IsftcfEuHH3RqerR3gH/faDNH/Cj/ANrHSjnQv2y3nQdINV8EWkmfq4bdXtFFL/U/I4/wlUh/gr14/wDuaRX+tudS/iunP/HQoS/9xI8X/wCEb/b10n/kH/Er4davjp/auj3Vvu+vknij/hKv28dJ/wCQh8Kvh/q+Ov8AZWuXFvn6ecOK9ooo/wBWHD+DjsTH/uNzL7p05fmH+sin/FwWGl/3C5X98KkfyPlD9orwb8Tv2h9Ah0z4w/sN3yahpzeZonirwt46tBqOlzA5ElvIF3rggHacqSASMgEcL4b/AG6f2rv2SvB97o37WvwP8S67pFpH5WgeP5NN8klzhYotR2bkBJIHmq25sDh2JYfdNUfEnhrw/wCMdAvPCvivRrbUdN1C3aC9sbyESRTRsMFWU8EVyS4ZzalVnXoZlU53Fr3oUXd2aXM4whez2bi2vNaHiZhLKsXWjicNgqdCunFuUJVXGaTXu1KcptTi1pdShON/cmtj5K/YE+PR/aL/AGhPFPj/AMcadDca9c+HYm0i8smJtLKxjkVHgiUliu55EfO45w3TJz9h18m6j+xv8SP2NfFd78Y/2BrO2vdNu0U+JPhZrdyWjvo1yc2V1IS8EvJIRmKknuAqV7D+zf8Atb/Cr9paxurPw1NdaT4l0k+X4h8G67D9n1LS5QcMJIm5ZQeN65HIBwcqM+C8Fjcgy7+zszq8+Ic6k+dq3tOeXNfm2lJL4tpaJcvKla8/4twnEGdpvDfVZckIRp83NTfJGz9jJ293qoO043fMpNuT9Rooor7Y4gooooAKKKKACiivOf2jf2o/hV+zH4Zh1nx9qM1xqWoSeToPhvS4vP1DVpyQFighHLZJALHCgkAnJAOVatSw9J1KslGK3b/r+uiZjiMRQwtGVWtJRit29v67LVt6JN6HbeK/FnhjwJ4cvPF/jPX7TS9L0+AzXuoX86xRQoOrMzHA/wAivlnXfHHxq/4KPx3ngb4Mi98E/Be6WS01zxxe2m3UPFEByksFhDIP3cDDKtKw5Bx2aM6XhT9mj4w/te+I7P4uftywrp3h61nFz4Y+DllcFrW2/uTak4x9pmx/yz+6OQQAzR19QWdnaadaRafp9rHBBBGscEEKBUjRRgKoHAAAAAHSvMcMTmq99OnRfTac159YRfb4mt3FOx4zhi86X7xOlh39nadRf3usIP8Al+OS+JwTsfJX7H//AAST+H37KHxx/wCF3H4p3/iO5sI508PWc2mLbCyEqNEzSMsjee/lOyghUHzE7emPrmiiuzA5fg8to+yw0OWN27a7v1ud+W5Xl+UYf2GDpqEbt2V9311bf/A0Ciiiuw9AKKKKACiiigAooooAKKKKACvGf2D/APkiGuf9lm+I/wD6mut17NXjP7B//JENc/7LN8R//U11ugD2aiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACvgz/gt18XNXj8O/Dj4L+Df2dfjF4z1XTPi74G8a3954B+Ems65YQaXYa/HPdBrqyt5IluEitpH+zlvMKtGduJFz950UAfnL+034Q0Hxd+3t8Cv+CtWufshfEfxv4CtvhprfhPVPDsnwtvZ/EPhS/a8E1lqcuhyxfbSrL9thJSFnjE0b42uGHr//AASJ+Enjn4feFPjL8QtW+DuqfDfwl8SfjZqfif4dfD7W7BbO70nSpbSzgaWW0B/0Frm5gubn7MQCgmBYBnYD67ooA+ePgF8MfDfwu/b9+L+n+GtS8Q3Meo/CvwPfXDeIvF2o6w6Svqvi4FYnv55mgi+UYhjKxKclUBY59z8Qf8hbQ/8AsKv/AOklxXlvgf8A5SF/FD/sjPgP/wBO3i+vUvEH/IW0P/sKv/6SXFAGpRXnH7QX/DXf/Eo/4ZW/4Vv/AMvH9vf8LB+3/wDTPyPs/wBj/wC22/f/ALGO9eb/APG3b/q3D/yv1w1sd7Go4eyqSt1jC6+T5l+R5uIzL6vWdP2FWVusYXT9Hzr8tz6Por5w/wCNu3/VuH/lfo/427f9W4f+V+sv7T/6cVf/AAD/AO3MP7Y/6hq3/gv/AO6H0fRXzh/xt2/6tw/8r9dJ8I/+HjH/AAsLT/8AhfH/AApT/hFP3v8Aav8AwiP9r/2j/qn8ryvtH7v/AFvl7t38G7HOKqGY881H2NRX6uFkvV870NKea+0qKH1esru13Tsl5t87su7sz2uiiuV+Onwc8FftD/Bbxb8BviPYfadA8Z+HL3RdYhAGWtrmB4ZNuejBXJB7EA9q9E9U6qvlz/goH/wVe+En/BOqacfEr9nP41+M7aw8MjX9Z1b4bfD1tR07SrDzZYjJdX0ssNtAwMLko8gbaVOPmXPwXN+1h8ZvEv8AwRW03/gl/L4iZPj9f/Fb/hmLUZVyXiWGbyp9UK53tb/2EokM2cFpN249/sf/AIK8/DDwd8Ev+CFfxk+DXw70sWWgeE/gjLo+iWa/8sbS2tkhiT3wiKKAPrf4deN9J+Jvw+0L4kaDb3ENj4h0a11Kyiu0VZUiniWVFcKzAMFcAgEjOcE9axP2gvjTbfs+fCjUvitdfDPxn4xXT5IEXw78P/Dsmq6tdtLMkSiG2QgsAXDMxIVEVnYhVJqj+yR/yal8Mf8Asnui/wDpDDXoLBipCtg44OOlAHyv8Jf+CtXwh8cfHTwz+zr8Yv2c/jN8F/E3jh5ovAyfF3wTHYWniCeKMySW1tdWtzcw+eIxu8qR0Y5AALMAfqmvyx/ac+GH7VH7PH7df7LPxh/4KVftQ2Hxu8B3XxitfC/w+07wf4Og8J/8I/4x1K2njsdRurQPdPqUIEcicXUXkMwfZICyn9TqAMvwf/yCZv8AsK33/pXLWpWX4P8A+QTN/wBhW+/9K5a1KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDE+IHw1+HvxX8OS+EPib4I0rX9Lm/1lhq9hHcRE/3grggMOzDkdjXzvff8E4tV+EN7L4k/YV/aH8R/DGdpDK3ha7lOq6BcMTkg2twSYi3ILqzFQflUV9R0V3YXMsbg4uNKfuveLtKL9YyvF/cn5nBi8swOOkp1Ye8tpK8ZL0lFqS9LteR+f37Wf8AwUw/bp/Yk8L2HhT41/s6+CZfEerSyDQ/F+maxNPpGoRw7PO/0TKTxuPMj4aRAd+QMDFdN/wSjktv2um8Qft9fGmaTWfH7a9caFpyzW+yx8PWkcUUgh0+Ms2wMtxhpCd5ywzku0n1L8d/2cvgn+014QTwJ8c/h/a+INMiuBPBDPLJFJDIBjdHLEySRnBIO1hkcHIrT+FPwk+G/wADvAtl8NPhP4RtdD0PT1ItbC0BwCTlmZmJZ2J5LMSx7k17dbOsreSOjh8P7PETdpSjonG92ldtpPS8VZabtPlPCo5Hmqz1V8Rifa4aCvCEtZKdrJu0Um462k7vXZNcx0dFFFfLH1gUUUUAFFFFABRRRQAUUUUAFeQftIfsbfD74/X9r490rVLzwj4+0kZ0Lx34ebyr22YDhJcEC4i7GN+xYAruOfX6KxxGHoYqk6dWN0/6uuqa6NNNdGc+KwmGxtF0q8VKL/Po09010aaa6M+ZfA/7YXxH+Animz+DH7fWi2ujXN1KIPD/AMTtNQjRNbPYTHAFnORyVbCdThF27vpiGaG5hS4t5lkjkUNHIjAqykZBBHUVl+OPAng34l+FbzwR8QPDNlrGkahF5d5p9/AJI5F9wehB5BHIIBBBFfNE/wAL/wBo/wDYGnfWf2fI9R+JHwpRi958O725MmraDHnLNp0rZM8Y/wCeDZPGBks0g87nxeW/xL1KX8284/4kvjX95LmXVS3PJ9pjso0q3rUf5t6kF/eS+OK/miudfajLc+raK4f4C/tF/CL9pXwaPGvwl8VR38KMI7+ykHl3VhL3inhPzRuMHrwcZUkc13FenSq0q9NVKck4vZrVM9mjXo4mkqtKSlF6pp3T+YUVT8Q+ItA8I6Hd+J/FOtWunadYwNNe317OsUMEajJd3YgKB6mvl3U/jD8dv2+NRn8G/sv3194J+FyTNBrXxSuLdo73WFB2vDpcbYKKeQZzgjnG0rtfnxeNp4VqFnKcvhit3/kl1k7Jeb0fJjsxo4Jxgk51JfDCPxPz7KK6ylaK7t2T6747/tmapb+OJf2dP2TvCkXjj4kMNt6BIf7L8OLnBmv5l4BU/wDLIHcSMHBKq2j+zl+xnpfwv8TTfG34y+K5fHnxQ1KP/iYeLNTjGyyUg/6PYxfdt4gCVG0BiCfug7B3XwI/Z8+FH7N3gaLwB8JfDEen2gPmXdwx33F9NjmaeU/NI59TwOgAAAHa1hRwVSrVVfGNSktYxXww9P5pf33/ANuqK35sPl1atWWJx7UprWMV8EPS/wAUu85K/wDKorcooor0z2QooooAKKKKACiiigAooooAKKKKACiiigArxn9g/wD5Ihrn/ZZviP8A+prrdezV4z+wf/yRDXP+yzfEf/1NdboA9mooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAPGfA/wDykL+KH/ZGfAf/AKdvF9epeIP+Qtof/YVf/wBJLivLfA//ACkL+KH/AGRnwH/6dvF9eoeKWNrJpurOjGGy1DzLgqpJVGhlj3YHYGQE+gyaANaisoeOfBJGf+Ew0sfW/jH/ALNS/wDCc+Cf+hw0r/wYR/8AxVAGpRWX/wAJz4J/6HDSv/BhH/8AFUf8Jz4J/wChw0r/AMGEf/xVAGpRWX/wnPgn/ocNK/8ABhH/APFUf8Jz4J/6HDSv/BhH/wDFUAalFZf/AAnPgn/ocNK/8GEf/wAVR/wnPgn/AKHDSv8AwYR//FUAfOVn/wAEjv2VrH/gpRN/wVJhv/FJ8fS2bougtqcH9hRXj2Cae+pJbeR5gu2tEEJk83aQSduTmrf/AAUD/wCCZ3hv/golo7+D/iF+1v8AGrwR4YvNBk0nXPCPw48TWFnpuswu5ZmuormxuDI+DtyGUbQBjvX0F/wnPgn/AKHDSv8AwYR//FUf8Jz4J/6HDSv/AAYR/wDxVAHj37H/AOwyv7IPw61n4Y237Wvxk+Imn6nY29np0nxL8S2d7NoUEMLxLHYtbWduIQVYZ3B+Y0xjBzVX/gn54f8A+GPfD37H7/tT/G4p4ZuVuLD4lx/EN4vFssyzSyh59QjiUTD980ZRoyjRqqspxXtf/Cc+Cf8AocNK/wDBhH/8VR/wnPgn/ocNK/8ABhH/APFUAfMfwq/4JC/Bfwf8cvDX7RPxs/aI+M3xt8S+CJnuPA7fGHxvHqFn4funXYbq2tLW3toBPt4EsiO4wrAhlVh9YVl/8Jz4J/6HDSv/AAYR/wDxVIfHXgsD5fFumueyx3qMx+gByfwoAXwf/wAgmb/sK33/AKVy1qVmeEIpo9DEk8LRme6uLhUdcMFkneRcg9DhhxWnQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAeD/Hr9iex8XeMj8ef2d/F8nw8+JkKk/27p0Q+yauOvk39vjbOjYAL4LDgnftArzTX/wDgq1a/s3xv8O/20Pgn4g0Tx1ZqhMHheGG6sdVgbcFvbaSWZNsTMjAqSSp4ySGC/YdfMn7eH/BNDwd+234m0bx2/wARrrwxrelWIsJbtNNF5Fc2gkeRYzGZI9rK8khDBv4yCDxjwMzweOw9KVfKtKresdOWV93Z2Sku6av1voz5fOcBmeEozxOSWVZvWDtySvvLldkpre6cebXmvoznPhN8NPHP/BSCz0r9oP8AaT1qC3+Gks5ufCHwu0S/LwXPlyMon1KZcec4ZSPKGApGCF+dW+t9M0zTdF06DR9H0+C0tLWFYra1tohHHDGowqKqgBVAAAA4ArlP2fvgl4T/AGcvg5oXwV8ES3Emm6FatHFNdMDJM7yPLLI2OAWkkdsDgbsDgV2Vd+XYN4agpVNaskueV7tu2qv2TvZKyS2XV+nlOAeDwynW1rTSdSTd25W1V/5U7qKSUUtl1ZRRRXoHqhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAV4z+wf/yRDXP+yzfEf/1Ndbr2avGf2D/+SIa5/wBlm+I//qa63QB7NRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAeM+B/+UhfxQ/7Iz4D/wDTt4vr2avMfib+yD8Fviz8SJfi54km8a6f4guNDtNIu77wj8UfEGgC5s7aa6mt45YtMvreOUxyXt0Vd1LDzmGcYAx/+GD/AII/9Dx8Zv8AxI7xr/8ALegD2aivGf8Ahg/4I/8AQ8fGb/xI7xr/APLeuR/aA/YC0bUvgP42074EfEv4w2Xji48I6lH4MvJ/2jvGWyDVWtZBaSN5mqsmFnMZO5WXA5BGRQB9KUV4z/wwf8Ef+h4+M3/iR3jX/wCW9H/DB/wR/wCh4+M3/iR3jX/5b0AezUV4z/wwf8Ef+h4+M3/iR3jX/wCW9H/DB/wR/wCh4+M3/iR3jX/5b0AezUV4z/wwf8Ef+h4+M3/iR3jX/wCW9H/DB/wR/wCh4+M3/iR3jX/5b0AezUV4z/wwf8Ef+h4+M3/iR3jX/wCW9H/DB/wR/wCh4+M3/iR3jX/5b0AezUV4z/wwf8Ef+h4+M3/iR3jX/wCW9cjrP7AWjSfHjw3qOj/Ev4wp4Hi8I63H4isz+0d4y3y6q91pR06QZ1XfhYE1QHawXMi7gx2FQD6Uorxn/hg/4I/9Dx8Zv/EjvGv/AMt6P+GD/gj/ANDx8Zv/ABI7xr/8t6APZqK8Z/4YP+CP/Q8fGb/xI7xr/wDLej/hg/4I/wDQ8fGb/wASO8a//LegD2aivGf+GD/gj/0PHxm/8SO8a/8Ay3o/4YP+CP8A0PHxm/8AEjvGv/y3oA9morxn/hg/4I/9Dx8Zv/EjvGv/AMt6P+GD/gj/ANDx8Zv/ABI7xr/8t6APZqK8Z/4YP+CP/Q8fGb/xI7xr/wDLeuR+Cf7AWjWHg29g+MvxL+MN3q7eLvEElnLD+0d4ywulPrF4+lx/u9VUZTT2tEORuyp3FmyxAPpSivGf+GD/AII/9Dx8Zv8AxI7xr/8ALej/AIYP+CP/AEPHxm/8SO8a/wDy3oA9morxn/hg/wCCP/Q8fGb/AMSO8a//AC3o/wCGD/gj/wBDx8Zv/EjvGv8A8t6APZqK8Z/4YP8Agj/0PHxm/wDEjvGv/wAt6P8Ahg/4I/8AQ8fGb/xI7xr/APLegD2aivGf+GD/AII/9Dx8Zv8AxI7xr/8ALej/AIYP+CP/AEPHxm/8SO8a/wDy3oA9mor5r+JH7AWjXXjL4fz/AA7+Jfxhg0i28XTSePIpP2jvGWbnSjo+pJHGu7VScjUH05/kKtiM87dyt13/AAwf8Ef+h4+M3/iR3jX/AOW9AHs1FeM/8MH/AAR/6Hj4zf8AiR3jX/5b0f8ADB/wR/6Hj4zf+JHeNf8A5b0AezUV4z/wwf8ABH/oePjN/wCJHeNf/lvR/wAMH/BH/oePjN/4kd41/wDlvQB7NRXjP/DB/wAEf+h4+M3/AIkd41/+W9H/AAwf8Ef+h4+M3/iR3jX/AOW9AHs1FeM/8MH/AAR/6Hj4zf8AiR3jX/5b0f8ADB/wR/6Hj4zf+JHeNf8A5b0AezUV81/Df9gLRrXxl8QJ/iJ8S/jDPpFz4uhk8BxR/tHeMs22lDR9NSSNtuqg5OoJqL/OWbEg527VXrv+GD/gj/0PHxm/8SO8a/8Ay3oA9morxn/hg/4I/wDQ8fGb/wASO8a//Lej/hg/4I/9Dx8Zv/EjvGv/AMt6APZqK8Z/4YP+CP8A0PHxm/8AEjvGv/y3o/4YP+CP/Q8fGb/xI7xr/wDLegD2aivGf+GD/gj/ANDx8Zv/ABI7xr/8t6P+GD/gj/0PHxm/8SO8a/8Ay3oA9morxn/hg/4I/wDQ8fGb/wASO8a//LeuR/aA/YC0bUvgP42074EfEv4w2Xji48I6lH4MvJ/2jvGWyDVWtZBaSN5mqsmFnMZO5WXA5BGRQB9KUV4z/wAMH/BH/oePjN/4kd41/wDlvR/wwf8ABH/oePjN/wCJHeNf/lvQB7NRXjP/AAwf8Ef+h4+M3/iR3jX/AOW9H/DB/wAEf+h4+M3/AIkd41/+W9AHs1FeM/8ADB/wR/6Hj4zf+JHeNf8A5b0f8MH/AAR/6Hj4zf8AiR3jX/5b0AezUV4z/wAMH/BH/oePjN/4kd41/wDlvR/wwf8ABH/oePjN/wCJHeNf/lvQB7NRXjP/AAwf8Ef+h4+M3/iR3jX/AOW9cjo37AWjR/HjxJqOsfEv4wv4Hl8I6JH4dsx+0d4y3xaql1qp1GQ41XfhoH0sDcxXMbbQp3lgD6Uorxn/AIYP+CP/AEPHxm/8SO8a/wDy3o/4YP8Agj/0PHxm/wDEjvGv/wAt6APZqK8Z/wCGD/gj/wBDx8Zv/EjvGv8A8t6P+GD/AII/9Dx8Zv8AxI7xr/8ALegD2aivGf8Ahg/4I/8AQ8fGb/xI7xr/APLej/hg/wCCP/Q8fGb/AMSO8a//AC3oA9morxn/AIYP+CP/AEPHxm/8SO8a/wDy3o/4YP8Agj/0PHxm/wDEjvGv/wAt6APZqK8Z/wCGD/gj/wBDx8Zv/EjvGv8A8t65H9n/APYC0bTfgP4J0747/Ev4w3vji38I6bH4zvIP2jvGWyfVVtYxdyL5eqqmGnEhG1VXB4AGBQB9KUV4z/wwf8Ef+h4+M3/iR3jX/wCW9H/DB/wR/wCh4+M3/iR3jX/5b0AezUV4z/wwf8Ef+h4+M3/iR3jX/wCW9H/DB/wR/wCh4+M3/iR3jX/5b0AezV4z+wf/AMkQ1z/ss3xH/wDU11uj/hg/4I/9Dx8Zv/EjvGv/AMt6774N/BvwB8A/AEHwy+GVhf2+k29/fXoGqa5ealcy3N5eTXt1NLdXsss8zyXFxNIWkdjl8DAAAAOoooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACvy0i/Zk+Gv7cXwj/bD/bB+OAvbj4m+D/ih440D4XeM49VnhvPAVr4cjNvpx0xkcCzPn27XchQDzmnbzN6nFfqXXxx8YP+CWfxM8U638V/CfwO/bNv/h98Mvjrqk2o/FHwVB4Kgv71rq6to7XUpdK1F50OnG8hiUSb4bnbIzyR+WzcAHu37D/xb8T/AB//AGLPhB8d/GqqNZ8bfC7w/r2rhIwgF1eadBcS4UcKN8jcdq+I/wDgoF+x9+yp8EPHfw4+HX7Dfw2k0j9qfxv8SNL1fwt4p0bWLubWLTS7fU4Z9a1TVrmSV5JNLFp9pgeKctHI9xHFGhbAX7msPgr458G+Ovh5bfCT4sxeGvhn4J8L3ej6l8NYfDUFwmr/ALq3i0+Rb52860FokMgEaAiXzvnI2DPzF8FP+Can7fHwM+Onj39oLRP+Chfw71zxN8RddF1r2v8Air9nm5u9STTo2/0bSIJ08RRpBaQISscccSruZpGDOxNAHV/8FNf2cf2YfE1lF8c/il/wTG8Q/tGeJV0ptLtbXwxHZS3emW8QlmRlF5fW/kZeVwJLVZLjcw+U7Vx8tfDnUdd+Of7E37Bn7HXxA+PF5448L/Fzxtqdv8SNattUvlfVtO0fTdX1EeHrma4WK5dI57W3spxKsckn2F1dRudT92/Hr4Lftz+M/Htzrf7Pf7ceheBfD13YRwtoOtfCCHXJrOZQQ09tc/brbazZB2zRzqCOBg4rz64/4JO+BPDn7I/w5/Z1+D/xn8QeH/FPwn8ZN4x8FfE2+tIL++XxBNPdzXt1dwERx3MN0b+9Sa3BjUpPtUoUQgA5r9jLwJ4W/ZD/AOCn/wAW/wBiX4G6Z/ZHwx1H4ReGfH+ieELWVzYeHNSn1DVNNvI7OIki3juFs7eZolwgdWZQNzZ+168I/ZK/Y38VfAz4leO/2iPjn8bv+FjfE74iJp1prXiO38Npo9jZaZYJKLPT7KyE05giVri4lYtNI8kkzMzcKB7vQAUUUUAfMH/BZn4r/EP4Nf8ABNj4keLPhT4ru9B16/8A7H8P2eu6fJsuNNXVtYsdLluonHMckcV5I6uOVZQwIIzXkUv7NPwY/wCCcn/BSX9mjwp+x94R/wCEP0L4u2vivwx8RNCsb2Z7fXPsOjNqlnqVykjsJL2KW0kQ3R/eut26uzAgV9e/tT/s3/Dz9r39njxd+zT8VRdroXjDR5LG8uNPm8u5tWJDxXMLkELNFKscqMQQHjUkEcV5F8Ef2D/jRpv7Q/hj9pX9sH9rgfFjXPh94bvtH+HlvY+BIdAttN+2iJLzULlI7mc3d9LFBHF5gMUSI0gSFTISAD2X9oD9nP4O/tSeAR8Lfjr4UfXfDrX8V3caQdRuLeG6ePOxJhBIhmiycmJyY2wNykDFfH//AATO8DfDKz/bk+N+rfsM6AdC/Zr07w9pnhxbDS7iQaBqvja2ubr+0rvR4ixSOKG3a2tZ5IAscs8ZxvMTNXrX7SX7Gf7Yn7QX7Ivjb9m2D/goPNoeu+L/ABffXEXjm1+HMKS6d4anuWdNBSG1vLdjsgK2xvRKkzoGb5WbK7H7Iv7L37Uv7OXgYfCLxV+0X8OLvwdpPhb+yfBeh/D34KSeHToUqhVimDT6xfJOqKG/dtGNzHcznkMAfGXxw+Bn7Pn7Lv7ePwI8K/s3fsX+Iv2fXi+NOn2Wp/Hmd0j0jxlZvBKG0AyWd1czXcmoOyQodTS3AdCVcybFe/8AtjfsJ+JtE/bY+Pn7bnxd/wCCVHw1/aM8C61pfh650t/EHimzj1zTbTTNJ8u++w2VxZTJO7tkiN57cuYABu3LX0dqv/BPr9qD44eL/A7/ALaP7dNn468I+AfGen+K9N8LeFfhXB4efVdUsJRNYyahc/bbozRxTBZTFBHbq7Iu75RtO9+0d+yj+3b8bdV8WeFPBn/BRKx8H/D/AMWwtayaLa/CC2uda0qzkgWKeGz1Nr1I0Zv3jLLLayvGZOD8q4APY/2cfij8L/jf+z94I+MXwSwPB/ifwpp+p+F0FuIfLsJrdJIEMY/1ZWNlUp/CQR2rtK5T4FfBjwH+zl8FfCfwB+F2nyWvhvwV4cs9E0O3ml8yRLW2hWGPe/8AG+1AWY8sST3rq6ACiiigD4d/aQ+FXgH9tb/grnpv7Jv7Svh2PxR8NPAv7PS+M7TwRqUjHTdR1vUNbnsBd3MAIW5a3t7FliEgZY2u3YAMQa6j/gj9qut6P8PfjP8As73Gv6hqOhfBv9oXxD4N8Ey6pfSXU9voiQWV/a2hmlLSSrbjUGtkLsWEcCLn5a7n9p39i/x/8Tvjv4a/aw/Zq/aAi+GnxL8P+Grzw1d6rqPhJdd03WdEuJo7g2l1Zm4tmLRXESywyxzIyM0gYOrlap/C39hn4jfAD9lq++DXwF/amv8ARfH/AIh8ct4t8ZfFfVfCVnqNxrWpXWpR3eps1i5WCJbiFXtIwp/0eIxldzRgkA47/gpZ+zf/AMEyfDvgfxV+2J+2/wDBuDxLqA06HTdMknvbu41Ke7K+TZ2GiwrL+4vppCFj+yqkjSNuZsKWHLeD/i3+19+zB/wTP+Bf7OHxA8R/2l+1D8RvD9p4Y0OTXLgXkmnXxgMt1ql+5P79NMs8yzuSRNNEke4tcKT0v7U3/BO39qn47ftt+H/2vvA37Z3hHS7DwVo/2bwD4D8bfBybX7Lw/fyLtudViaLWbISXki5jWWSNjFGSqEZZm9T8b/sLfBz9qD4beFfD3/BQz4Z/Dv4z+I/DK3Ri1u/8Ara2aSTuu97aznuLprbckcCsPOfcYg2RkKAD8+P2edf1X/gnZ/wSX/b8u/2f/FOoy6v8OfjJ4yh8Pa/qF6bm/N3/AGPpES6lLI2TJP5rm4ZjwXycY4r2Dxp+yT8Hv+CZPx9/ZN+IP7LWm3Glan44+JS/D34oXMepTyv44tb3QdRujf6kXdvtV1Fd2EVwtw2XBd13bGK16f8Asz/8ER/2Nv2dfAfx5+Gtp8PfDk+k/HXV9Xiv10TwzHpk2k+Hb61hhXQ4pEkctFC0csqSDYA82RGpXJ1fgr/wTj+MWh/Fr4a/ED9qb9sy6+KemfBa0uU+GGif8IPBpDxXcto1iNR1OdLiX+0btLR5YkdEt0BmeTyy5BAB9ZUUUUAFeX/tu/FvxN8Af2L/AIvfHfwWqtrPgr4X6/r2kq8YcG5s9OnuIsqeGG+NeD1r1Csvxt4M8M/EbwZq/wAPfGukx3+ja9pdxp2rWE2dlzbTxtFLG2OcMjMp+tAH5jv+zL8Nv2IPg/8AseftifBH7bb/ABP8YfFDwNoPxR8aSarPNeePLbxGgt9S/tNnci8/fXC3cZcHyWgXy9ijFfpT8XPhR4I+Ofw31b4S/EmwurvQdcthb6pa2ep3FnJNFuDFPOt3SVA23B2sCQSOhNfLfwg/4JY/EvwrrXwo8IfG/wDbNv8A4gfDD4FapDqPwv8ABM/gqCxvRc2ttJa6bJquopO/9omzhlby9kNtukVJJPMZefXfiZ8CP2s/GXhH4x+HPCP7bDeH7nx0kEXww1GP4f2sr/DyMWkUM+zbNG2pPJKs06yTMhiaUKMqgyAfMH7O3wW+Bfw4/wCCutv4H/4JueBYfCngb4feANVsP2jV8MzSR6Be6zcvaPo+nmLcYpNWgC3U8sqjzI4p1SR8yBK8f/bt8ZXv7Z/x6+B/7YsfiGRfhn4H/a/8FeEfg/ZR3W2HW511jZrHiJ1BxJE00AsrRjkCK3uJl+W6Uj67/wCCfX7Cn7Uv7Dvh3w/8I739qP4ca/8AD3R4bhr/AEXRPgpd6VqurXsqsz31xqU2vXZkuJJ286WR4XaUkjK5BHG/tHf8G/X/AATb+NMPhH/hAP2XPhn4Hn0D4i6T4i1240/4fW0za9p9rOZLnSZdrx7YrlTsdzvAHJjfpQByv/BRX9gT4l/Hb/goFpf7UQ/4J+/DH9oXwbpfwSXw7H4a+InjC30zyNT/ALWluzNaiayuleQQkIN4iQ+cf3owa+nP+CdHxi+BPxy/Y58HeNf2cPhY3gTwtbw3Wkw+BJLCK1fw5d2V1LaXenNFESiGG4hlT5flYAMOGFUfjN+zx+2bf65bWP7Jn7aHhv4Y+ELbw/baZa+FdR+DkGt/2eYQyia0n+3W3lnYY1EcqTRr5QwuCQer/Y0/ZS8EfsVfs7aH+zz4E17VNYg0uW7u9R17XJVe91fULy6lu7y9nZFVd8txPK+AAFDBRwooA9RooooAK+Mf+Cj+gad+0B+2t+zF+xD8SxNefDbxxN4w8R+OPDguXit/EB0WwtPsdjdbCDNbefqHntASUkNqm4MBivs6vEv2xf2P9S/aT1LwH8T/AIZ/FubwB8Sfhfr0+qeB/GC6KmpwQi5tntbyzurN5Ixc2s8D4dFkicNHG6yKU5APHv8AgnD4f039n79tj9pz9iL4ZLNZ/DbwRJ4P8SeB/DZuXlt/D51qxu/tlja7yTDbedp/nrApCRtdPtCg4r079uT9mT/gn54+8OXf7SX7fPgfw/qvh/wJ4eme4vvGV7M+maZahjI832Uv5JmJwFk8szE7UQ5IBzvg5+wz8VfhB8O/jB4isv2qZbv44/GNmudW+L7eCrcQaVdw2Is9N+y6Q8rxfZbNFVkt5ZZDIzSmSRvMOOS/bf8A+Cdf7TP7X3ij4TavaftneHbHSPhqsWoap4R8W/CRtY0rxP4giUCLVrqC31WyB8pgZIrZi8SSHfhiq7QD598P/sfftR/tRf8ABBnxh+zvo/gfUZp/G/js6r8JfBHxK1p0vNM8FjxTa3+nadqE9x5joU06EnY5kdI2SIgsuwd7+yF4y+Cn7HHxY+JvwJg/4Jg+BP2fPijb/Ce58b6enw91G21PSvGGjWUjRNsvIbS0l8yC5ljV4JYUYC4V1LKc19NH4S/tx33wDuPBuqftmeFbb4inWlubLx1onwfEOnpZqUP2SXS7jU7gybsOGlW5jbDjbtK5blv2ff2EfiD4X/aO1f8Aa7/a1/aNi+Knjy98Et4P0ZdO8Fx6Doui6LJcpc3EEFl9ouXeSeaOJpJpZ3JWJEUKowQD4XsPgd4R+Av/AAS2+Av/AAVw8KXd7N8fdV1z4feLPG3xCbUpm1DxYviPVtPg1LSrxt+JrQw6pJGlvjZCIIzGEKZr9eq+KPh9/wAEivGHhXTfAfwD8V/tg3+v/AL4X+MbXxD4J+F03g2GK/DWVwbnTbC+1b7QxvLK0m8tkiFvG7CCJZJHCnP2vQAUUUUAFflpF+zJ8Nf24vhH+2H+2D8cBe3HxN8H/FDxxoHwu8Zx6rPDeeArXw5GbfTjpjI4FmfPt2u5CgHnNO3mb1OK/Uuvjj4wf8Es/iZ4p1v4r+E/gd+2bf8Aw++GXx11SbUfij4Kg8FQX9611dW0drqUulai86HTjeQxKJN8NztkZ5I/LZuAD3b9h/4t+J/j/wDsWfCD47+NVUaz42+F3h/XtXCRhALq806C4lwo4Ub5G47V8R/8FAv2Pv2VPgh47+HHw6/Yb+G0mkftT+N/iRper+FvFOjaxdzaxaaXb6nDPrWqatcySvJJpYtPtMDxTlo5HuI4o0LYC/c1h8FfHPg3x18PLb4SfFmLw18M/BPhe70fUvhrD4aguE1f91bxafIt87edaC0SGQCNARL53zkbBn5i+Cn/AATU/b4+Bnx08e/tBaJ/wUL+HeueJviLroute1/xV+zzc3epJp0bf6NpEE6eIo0gtIEJWOOOJV3M0jBnYmgDlP8Agoh+wB8TPjX/AMFDov2qZf8Agnf8Mf2h/B1j8DrTw3B4d+IXjG20yS21OPV727kktFnsrpHk8mWNB5nkofNx5owaofHr4T+FP+Cov/BMn4AXn7Ev7Knhq98G+HfixpOq6j8HPG1zDo1haWOjvf2d/o1yFhnSMJcI1sQkUoP3grLX1V+0H8Ev27PHXjq61f8AZ1/br0L4f+H7zTY7dtE1f4PQa7PZzDcHuba5N9b7XYFTtmjnQFfu4JFYHgf9hf4pfs0/sn+CP2Zv2I/2oj4MuPCd9c3WqeI/GfguHxI3iOW6luLm7ku4hPasskt3cPcFoZY9p+UDbxQByP8AwS38RfAvwT4v+J/7JvhP9gzw3+zt4/8ABdzpmp+MvB3hG4tbrTNWtb6KUWWp2t5bwwfao2FvNG2+GOSNoirKMivsGvAv2Qf2KvEf7P8A8S/H37RXxs+O1z8Svif8SV0628Q+Jf8AhH4tIsbTT9PSVbOwsbGOSX7PChuJ3YtLK8jyFmY4GPfaACiiigD5g/4LM/Ff4h/Br/gmx8SPFnwp8V3eg69f/wBj+H7PXdPk2XGmrq2sWOly3UTjmOSOK8kdXHKsoYEEZryKX9mn4Mf8E5P+Ckv7NHhT9j7wj/wh+hfF218V+GPiJoVjezPb659h0ZtUs9SuUkdhJexS2kiG6P711u3V2YECvr39qf8AZv8Ah5+17+zx4u/Zp+Kou10Lxho8ljeXGnzeXc2rEh4rmFyCFmilWOVGIIDxqSCOK8i+CP7B/wAaNN/aH8MftK/tg/tcD4sa58PvDd9o/wAPLex8CQ6Bbab9tESXmoXKR3M5u76WKCOLzAYokRpAkKmQkAHsv7QH7Ofwd/ak8Aj4W/HXwo+u+HWv4ru40g6jcW8N08ediTCCRDNFk5MTkxtgblIGK+I/2Gk+HPwn/ac/aP8Ai7+wf4RbTP2cPB3gK306HRtLuJBoOt+ONPe9l1G40eIkxxxR2/2a0nkhCxyzxnG8xM1e7ftJfsZ/tiftBfsi+Nv2bYP+Cg82h674v8X31xF45tfhzCkuneGp7lnTQUhtby3Y7ICtsb0SpM6Bm+Vmyu9+xp+y/wDtFfs4+Frf4R/E/wCNfwx8Q/D3SPDiaT4b8HeBvgvN4bTT1Uqo3SS6xfLLH5YdTH5almfcXPIYA/N79hP4j+Frb4JfBf8A4KZ/tqf8E7v+EgPjrxZpE2tftLa14/W58R6drOoagtvb3Y0wR/6HoqXkkVrDFDc8W4jZrbDEH6M8Ffsk/B7/AIKcftB/tY+PP2ptNuNV1HwP8ST8PfhhcS6lPE/ge1s9B066+36aUdfst1Ld38tw1wuHJjRd2xQtdj4T/wCCO3jLQ/BfhX9lbXf2yr/VP2c/BPjG017w/wDCt/BMEepPFZ341Cx0q61n7QxuLGC5SJggtkmZIURpiBmuy+NX/BOX4x638W/iV8Q/2WP2zLn4V6b8aLO2j+J+i/8ACDw6u8t1DaCx/tHTJnuIf7Ou3tEiid3S4QmGOTyw4JIB1f8AwSY+O3j79pr/AIJp/BH46fFPUJLzxJ4h+HenTa5fzD5726SMRSXLf7UrIZDjjLnHFfQ1cr8Dfgz4B/Z0+DHhT4B/CzS2svDfgzw9Z6Lodq8m90tbaFYo97fxuVQFmPLMSTya6qgAooooA+A4/wBmr4Mf8FG/+Ck/7S3hP9sHwh/wmGg/CKz8KeGPh5oN/ezJb6J9v0ddUvNStkjdRHeyS3UcYuh+9RbRFRlANeuf8EZvit8Q/jJ/wTa+HPir4q+LLvX9d09tZ8P3mu6hJvuNSXSdZvtLiupXPMkkkVnG7OeWZixyTUvxv/YQ+NGpftD+Jv2lv2Pf2tx8J9e+IHhux0b4h2994Eh1+21L7EJUs9Qt0kuYDa30UU8kQkJlidBGHhYxgnqPhh+xxrv7OHwT+D37PH7LHxvu/CPhX4aapbt4kg1HQLfVbnxhpqw3H2i1mmlKm1mnuplunuYhu3oyhQrnAB8w/wDBX/8AZP8A2H/h58HfFvxM0P4O3WoftI/FK8m074L6romt3Z8UT+LZkP2OTTpzNvs7e2cJcTeWY7eKCFy4wcNzv/BRvxt8efG37WH7NX/BPDxh8Ipvi2mufDXVvEfjjwhD4qOg6N4r1myS0gRtUu1jZl02EteXBhWKUSzPaq0LAceveJ/+Cb/7a0n7cfi39t/wT+3j4EOq6xYrpPg3T/G3wIuNYbwbow5awsZItftUXzXAeabylkmYKGO1VUemftK/sR/EL44eIvhd8evAn7Qlt4L+M/wus7u1sPHEHg1b3TNTgvreKLUbW50uS5VmtpnhilRFuRJC0a7ZW+bcAfKWvfBrQv2wf+CWX7Qn/BPP9lT9jbRPhH8RfDvjax0jxd8JG8QxSaRb3zT6XqAube7VFjazuLARyqywxkkODCG+96d/wTzj+BP7OX7XGufspah/wTG8B/s6fEjX/A58RaVf/DrU7XU9L8VaNbXccEyreRWdpIs0E08Ja3lhHyyh1Zhk16X8KP2C/jR8FPhd8QL/AMBftfyf8Ln+J/jODxL4x+K2p+A7a4triaGK3torOPSvOVYrNLS2jt0jE5lUFn84seLv7PX7DXxQ8J/tO3P7ZP7V37TSfE7x9B4Ok8LeGF0fwZH4f0fQNLmuY7m5EFoLm6keeaWGEvPJOx2xKihVyKAPpCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDzP9sX9rT4O/sMfs0+Lf2qvjzq81p4Y8Iab9pvRaxh57qRnWOG2hUkBpZZXjiQEgbnG4qMkfLnw9+Mv/BwB+0L4Ls/jf4C+An7NXwu0PW7Vb3QvAHxP1PX9Q19LZxujF7cWPlwWsrIVJQRSNHnDqGBUc1/wdBaBrd5/wAExIvHEGk3F/oPgv4reGNf8aWdvEZDLpEN55c25B95Q8sTHsAuTwM1+gnhPxX4a8eeFtN8b+DNdtdU0fWLCG+0rUrGYSQ3dtKgkjljYcMjIysCOCCKAPiD9tv/AIKRftsfsif8E5/Df7TPjz9m7wl4P+J938T9L8LeIPCOrapLrWmJb3Govatd209tJbs6ywqk8W45TzArqxU1931+dn/BzPdWt3/wTp0Q2tzHJ5fxz8IJJ5bhtrDUBlTjoR6V+idAHyr+xZ+3H8Wf2jf2+P2q/wBlnxv4e8O2vh/4Ga94ZsvCV5pVpOl5dx6jp81zObt5JnSRleNQnlpEApOQx5Hy3+wx+3d/wXy/b2/ZBg/bN+DHhb9lC40661DVYLHwVqWi+I7LUb02N1LbtEtz/aEsEckhiOxmGzLDcVGSO/8A+CVv/KYz/gol/wBjh4C/9Mt1Xy3/AMEH/AP/AAWC+IP/AASt0Twv+yT8e/gT4F8B6j4h8SQadrmv+DNW1HxPprtqlys0yFbtbN2Ehdow0WANobJyaAP0y/4Jf/t8eGv+Clf7GXhf9q/QfBVx4ZudVkurHXvDV1cec+l6jazNBPCJNq+Ym5d6NtUlHXKq2VHG/wDBRr9v74xfs5fF34Q/scfsk/CXQfF3xk+ON/qkfhRfGOqy2eiaPZabbC5vL69eFWlkVYz8sUeGfa+DlVR+/wD+Cbv7B/w+/wCCbX7IHhf9kv4d+Jb3XYdC+0XGqeIdSiEc+q39xM01xcsgJEYZ3IVMttRUUsxBY8//AMFE/wDgmL8I/wDgohZeD/EOv/Ejxl8PvH3w41G4vvh78Svh9q/2PVdEmnVFmRWIIeKQRx70OCQgAZctkAzfgHq3/BZ/RfjT4e0j9q7wr+zjr3gDUWuE8Qa18MbrW7DU9HZbaV4XW31BpY7lGmWKI7ZFYCQttwpr3f4x/tB/AT9nbQYfFX7QPxv8IeBdLuJTFBqXjHxLa6ZbyOBkqslzIiscHoDmvze1j4q/8FTP+CRf7X/wH+Fv7SH7aen/ALR3wf8Ajj8RbbwNBJr3g630nxF4ev7oqsE6y2zN9pjVmDO8jP8AKrDbGWVq2f2SPgr8H/22P+C0n7X3jr9sjwHo3jjX/hFqHhvw18NPDHjCwjvrTw5olxYPcG5trWcMivcyDzDNtLAlgpAcggH6LfDL4ufCj41+E4/Hvwa+J3h7xboUsjRxa14Y1qC/tHdQCyiaB2QkZGRnjIrl/A37ZX7IHxP+Is3wg+Gn7Vnw28ReLbdnW48L6F450+71GIpneGtopmlXbg5yvGDmvi3/AILzeDPCH7EP/BGX4wWX7HngLRvhfYeLvEWkxeL7rwNo8WnRww399Y2F9dmO3VVDy2yR27sBllbnnmuR/wCC0v8AwT4/YK/Zf/4I3+Ivid+z38IPCXw/8QfB/TNI1j4XfEHwvp9vaataajDeWyW8i30SiWd7gsFdmZvMaQOcuFYAH6ReMvjb8GPhz4r0nwJ8Qvi74Y0HXNetL260LRtZ1+2tbvUYLOLzruWCGV1eZIIj5krICI1+ZiBzWb4E/af/AGafij8PdV+Lfwy/aH8DeIvCmhXUttrnifQvFtneafp08SJJLFPcxStHC6JJGzK7AqsikgBhn81/+CgHwj8Pftq/8FOv+Cb/AIP/AGmvCkd7ZeI/BXjPWPGPhy4jKwXk8WiafetaTx9HhNxGqyQsCroGRgQxFVP+C13w2/4RX9rP9kb9ib4AfsZeD/E/w68b+K/E/iXxF8HbTV7XwlovjTWNM061NnFe3CW7xMIU/e+VJG4n8qOIjhSoB+mPwY/al/Zk/aQN8P2eP2jPAnj3+zCBqX/CF+L7LVPshJwBL9mlfy8kH72Old3X5P2/7IH7evib9uj4CftJfCT/AIJDfDL9m9/AnjFLfx74m8B/F7TLoa14VuU8m9sLiytNPtBcBVKyxli5Ro8KoJBH6wUAfNPgz9sz4kfGj/gpd41/Y++Duj6CfA/wh8D2lz8T/Et/aTTXZ8Ral+807TbQpMkaLHapJPOzLIxLxxgRnLHE/wCCSn7ePxZ/bS+G/wARPB/7Tnhjw7oPxc+D/wAUNV8HeP8AR/C1tPBYs0Eha1vLeO4mmkWGaE8M0jbmikZcKQB5X/wQfaXU/H37bfiPxPk+JJv21/F9pemT/WCwt4rNbFOeTGqNIEPp0rnPjH4h0H/gmj/wXq0r48eJdVh0T4XftZ/DmfSvF2oXD+Xa2XivQIfOtrqZhwvmWP7lRjLPJI2Tg0Ae6eNv28Pi/rP/AAV/8H/8E5fgX4c8N3nhzSPhpe+M/jZr2p2dxNd6bDI4g0y0tHjnjjhneYo7iVJd0MoKhdpJzfh78VP+Cq/7Qn7Jfgb4m/s+fGD9kPVvF95qesR+Mda0r+2dd8LXMEV48VoumzWd6r+aiIVuPMdwJQyqF2kV5v8A8EAfDGvfHHwz8ZP+CsfxH0qaDXv2mfiPcah4djvE/fWXhPTWex0m2OeQQqTZIwHURNjoav8A/BsH/wAoYvhr/wBjB4q/9SLUaAPPPgj+2h/wXn+OP7bHxv8A2ItE1b9kWy1r4GweHJdb1m68F+KDa6iNYsDewiALqhceWg2tvA56ZFfoj8Aofj/b/CPR4f2pNS8HXfjxUm/4SC48AWV3b6Q7edJ5X2eO7kkmUeT5Qbe7ZcORgEAfEP8AwT5/5WAf+ChH/YP+Fn/qNtXvVh+1h+31c/tHt8K73/glN4itvAY8WyaavxSb4u+HGtzpi3DRpqv2AXH2vY0QE3kbPNAbaV3AigDL/Zb/AG4/iz8bv+CoP7Uv7FHivw94dt/CvwQtfBcnhTUNPtJ01C7Or6Sby5+1u8zRyBZBiPy448Lw28819U1+eH/BPn/lYB/4KEf9g/4Wf+o21fQn/BWj9qDVf2Pv+CdvxT+N3hR5T4lh8NtpXg2K25ml1vUHWxsBGo5dhc3ET4HOEbpjIAPOP2e/26f22f2s/wBlz4xftE/s1fBTwL4muNP+L2peG/gTpV/qU+mW2u6JYX0NjPql7dvJIGzIt9IqxJHlbdUwWbNVP+CT/wC3R+3B+0z+0F+0V+zX+3T4L+F+j+JPgnrXh+yg/wCFXR6gbWX+0bS4umEkt7M7TFFSFdyxxDdv4YbTX0B+wL+zBpf7F37Fnwx/ZZ0tIs+CfBtlp+oTQ/duL4Rh7ucf9dLhppPq9fKf/BLH/lL5/wAFDf8AsdvAv/pknoA+2P2g/j18Lf2Xfgl4n/aF+NfiaPSPC3hDSJdR1m/k5KxIOEReryOxVEQcu7qoyWAr48/4I7f8FLv2wf27Pj3+0H8Jv2tvgb4Y+H8nwxk8K3nhjw/pEF0NRtbHXLO8v4YNSkmnkSS6jt0tFfy44QshmBXoF8+/4Kt/HH4ia7/wUI+G/wAGPi9+xP8AH/x38AfhzY2/jbUl+E3wmvvEFt4v8UiVhp9ndvEFiFpZBTctEXYyTGIOhVQa80/4JLft36b44/4La/tevH+yb8dtK/4WzrXgRIBrnwvubY+E/sWhXaE67ub/AIlYn6wGTPmryKAPu34V/tmfEJf+CkfxE/YA+O2iaHZyJ4QsvG3wf1nR7aaE6zoLv9lvYLkSyyKby2vFwTHtDwyo3lptJb6Tr8+v+CgrzaT/AMF3P2BdQ8J5GqalY/Eyy11Yv+W2mJolvKolx0RZcsueC9foLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAGf4t8JeFvH3hbUvA3jjw7ZaxousWMtlq2lalarPb3ltKhSSGWNwVdGVipUgggkGvjDSP+CE/wAFfh5aTeEv2df23f2oPhR4Kkmd4Ph38P8A4xyQaPZB2LOlstzBPPbKSScRTL14Ir7fooA+TvjP/wAEa/2S/i/+wnpv/BPaz17x34U8FaV4li8QW+reHvE/m60+pLdyXj3Ml5qEd0XkkuJZJHYrnLfLtAAHN+GP+CM+ueGfEuneJH/4K/8A7aupDT76G5Onap8YbGW2uvLcN5UyDTAXjbG1lBGVJGRX2rRQB4z8AP2HPhN+zl+0r8Z/2pvBHiHxFdeIPjnqWkXvi2z1W7geztJNOtZLaAWiRwo8askjF/MeUlgMFRwT9gf9hz4Tf8E6v2atL/ZZ+CfiHxFqnh/SdSv722vPFN3BPeNJd3UlzIGeCGFCoeRguEBCgZJPJ9mooAK8H/bF/wCCfPwx/bK8Q+GvHmufF74oeAPFXhGC6t9B8WfCrx5caJfQwXLRNNC+wNFOjGCP5ZI2HBx1OfeKKAPkf4Jf8Ebf2ffhl+0DoP7Ufxd+Ofxi+N3jfwisv/CF6t8afHf9rR+HXkG2SWztoYYII5CP4zGxBAYEMoYbv7Vn/BKf4A/tQ/G20/ae0b4lfEn4T/E+30kaVdfEL4O+Lv7G1HUtPB3La3YaKWC6jU4x5kTMNqjdhVA+m6KAPCvhj/wT4+DXg79mjxb+yr8VPGnjr4veHPHlzczeL7z4v+LJdav9RE8EMDR+cQnkxqkEflpCsYjYF02sS1eI+F/+CBf7Kthd+F9C+Jv7Qfx2+JPgHwVqMF74U+EXxF+Jbah4Y0+S3/49l+yiBJJ44RgRxzyyIFG0gqSp+46KAPH/AIs/sU/Cv4x/tdfCT9tDxPr/AIgg8U/Bmz1628L2FhdQLp90mr2qWtybpHhaRyqIDH5ckeGyW3jipf2yP2Iv2e/27fhna/DH9oDw3eTx6VqsWq+G9d0TU5bDVdB1GLPlXtldwkSW8y5PIOCDhgw4r1uigD5U+CP/AASl8PfCP4p6D8VfF/7d37TPxLl8NXf2rRtD+I/xbe70yOYIyLJLbW0Futyyhjjz/M555NfVdFFAHyZ8F/2WvjH+zL/wVQ+KHxc+Hng4ah8Ifj54ZsdZ8UXkOoW8Z8NeLtNUW2TbySLLJDfWrhi8SyFZrc7wisGPX/8ABSr/AIJpfs8f8FUf2fbf9nT9o6/8Rafplj4gt9a03V/Cd5Bb6hZXcSSRho5J4JkCtHNKjAoch+MEAj6EooA5j4J/CDwN+z78HfCvwK+GWmGz8O+DvD1nouiWzEFo7W2hWGMMQBubagJbAyST3rhv2Ef2KfhX/wAE9f2ZND/ZS+C+v+INT8O6Beahc2d74ouoJr13vL2a8lDvBDDGQJJ3C4QYUKDk5J9gooA8Z+Dv7Dnwm+CP7YHxj/bX8KeIfEVx4q+N8OgR+K9P1C7gfT7QaRZGztvsiJCskZaM5k8ySTLcrsHFezUUUAfFfxq/4Ik/DX4rftb/ABC/bO8D/tz/ALSHwr8VfE9dKXxbafCnx7Y6VY3I06xisrYbG0+WQ7Y4y3zyN88shG0NtHPan/wRa8anx98NIdZ/4KAfGP4neCPDPxV0rxx4r0X43eLI9anluNIgvDp1vYGC1gWGN7q6WW4Em8SC1gwAU5+9aKAON/aB+EE/x8+D2ufCK2+LXjLwK+tQRxL4s+H2rpYaxp22VJN9tO8cqxsdmwko2Udh3yPjP4S/8G/Xw8+Cvxf1j45eBv8Agpr+13D4h8T6tY6h4xun+KOnD/hI5LQbYFvimlq1wgjzHgtnYzAEZr7+ooAK8b+Bn7EPwo/Z/wD2pfjR+1x4N8QeIbnxJ8dLjQpvFtlqd3A9jaNpNnJaWws0SFJIw0cjGTzJJcsAV2Dg+yUUAfJnw/8A2WfjH8S/+CtPjD9uf46+Dho/hjwB4Cg8DfBGxl1C3uH1Bblxd6rrbJDI5ty7lLSNJNshjidmRMrn6zoooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9k=" + } + } + ] + } } considerations: { users: "Who are the intended users of the model?" + users: "Data scientists and ML researchers" useCases: "Who are the intended users of the model?" + useCases: "Text-to-image generation for creative applications" technicalLimitations: "What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance?" + technicalLimitations: "Limited performance on non-photographic styles" performanceTradeoffs: "What are the known tradeoffs in accuracy/performance of the model?" + performanceTradeoffs: "Higher resolution output requires more computational resources" ethicalConsiderations: { name: "The name of the risk" mitigationStrategy: "Strategy used to address this risk" @@ -62,5 +81,13 @@ components { mitigationStrategy: "With respect to the benefits and harms outlined, please describe any mitigation strategy implemented." } } + properties: { + name: "modelcard:custom-property" + value: "custom-value" + } + properties: { + name: "modelcard:another-custom-property" + value: "another-custom-value" + } } } diff --git a/tools/src/test/resources/1.6/valid-machine-learning-1.6.xml b/tools/src/test/resources/1.6/valid-machine-learning-1.6.xml index aff626821..4c04a0d7d 100644 --- a/tools/src/test/resources/1.6/valid-machine-learning-1.6.xml +++ b/tools/src/test/resources/1.6/valid-machine-learning-1.6.xml @@ -32,7 +32,7 @@ - string + byte[] @@ -61,15 +61,19 @@ Who are the intended users of the model? + Data scientists and ML researchers Who are the intended users of the model? + Text-to-image generation for creative applications - What are the known technical limitations of the model? + What are the known technical limitations of the model? E.g. What kind(s) of data should the model be expected not to perform well on? What are the factors that might degrade model performance? + Limited performance on non-photographic styles What are the known tradeoffs in accuracy/performance of the model? + Higher resolution output requires more computational resources @@ -86,6 +90,10 @@ + + custom-value + another-custom-value + diff --git a/tools/src/test/resources/1.6/valid-machine-learning-considerations-env-1.6.xml b/tools/src/test/resources/1.6/valid-machine-learning-considerations-env-1.6.xml index 2b4938c19..d4c54bc45 100644 --- a/tools/src/test/resources/1.6/valid-machine-learning-considerations-env-1.6.xml +++ b/tools/src/test/resources/1.6/valid-machine-learning-considerations-env-1.6.xml @@ -7,7 +7,7 @@ meta meta-llama - llama-2-7b + Llama-2-7b https://huggingface.co/meta-llama/Llama-2-7b diff --git a/tools/src/test/resources/1.6/valid-metadata-timestamp-1.6.textproto b/tools/src/test/resources/1.6/valid-metadata-timestamp-1.6.textproto index ea94ddb7f..f276e2f86 100644 --- a/tools/src/test/resources/1.6/valid-metadata-timestamp-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-metadata-timestamp-1.6.textproto @@ -6,7 +6,7 @@ version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" metadata { timestamp { - seconds: 3173618478 - nanos: 3 + seconds: 1586809239 + nanos: 0 } } diff --git a/tools/src/test/resources/1.6/valid-metadata-timestamp-1.6.xml b/tools/src/test/resources/1.6/valid-metadata-timestamp-1.6.xml index 1136bc466..ed8322eb0 100644 --- a/tools/src/test/resources/1.6/valid-metadata-timestamp-1.6.xml +++ b/tools/src/test/resources/1.6/valid-metadata-timestamp-1.6.xml @@ -1,7 +1,7 @@ - 2020-04-07T07:01:00Z + 2020-04-13T20:20:39Z diff --git a/tools/src/test/resources/1.6/valid-release-notes-1.6.json b/tools/src/test/resources/1.6/valid-release-notes-1.6.json index 46c5a7c3b..0be9e48a5 100644 --- a/tools/src/test/resources/1.6/valid-release-notes-1.6.json +++ b/tools/src/test/resources/1.6/valid-release-notes-1.6.json @@ -44,7 +44,7 @@ "type": "security", "id": "CVE-2019-9997", "name": "CVE-2019-9997", - "description": "Great new feature that does something", + "description": "A security issue was fixed that did something bad", "source": { "name": "NVD", "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" @@ -112,7 +112,7 @@ "flow": "outbound" }, { - "classification": "pubic", + "classification": "public", "flow": "bi-directional" }, { @@ -166,7 +166,7 @@ "type": "security", "id": "CVE-2019-9997", "name": "CVE-2019-9997", - "description": "Great new feature that does something", + "description": "A security issue was fixed that did something bad", "source": { "name": "NVD", "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" diff --git a/tools/src/test/resources/1.6/valid-release-notes-1.6.textproto b/tools/src/test/resources/1.6/valid-release-notes-1.6.textproto index e39791f99..9870ee17c 100644 --- a/tools/src/test/resources/1.6/valid-release-notes-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-release-notes-1.6.textproto @@ -18,6 +18,10 @@ components { featuredImage: "https://example.com/featured_image.png" socialImage: "https://example.com/social_image.png" description: "The main description of your release" + timestamp { + seconds: 1631839878 + nanos: 0 + } aliases: "Project Orion" tags: "CMS" tags: "SEO" @@ -28,18 +32,36 @@ components { description: "Great new feature that does something" source { name: "Acme Org" - url: "https://issues.acme.org/17240" + url: "https://issues.example.com/17240" } } resolves { type: ISSUE_CLASSIFICATION_SECURITY id: "CVE-2019-9997" name: "CVE-2019-9997" - description: "Great new feature that does something" + description: "A security issue was fixed that did something bad" source { name: "NVD" url: "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" } + references: "http://some/other/site-1" + references: "http://some/other/site-2" + } + notes { + locale: "en-US" + text: { + content_type: "text/html" + encoding: "base64" + value: "PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5SZWxlYXNlIG5vdGVzIGhlcmU8L3A+" + } + } + notes { + locale: "es", + text: { + content_type: "text/html" + encoding: "base64" + value: "PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4=" + } } } } @@ -50,7 +72,7 @@ services { url: "https://partner.org" contact { name: "Support" - email: "support@partner" + email: "support@partner.org" phone: "800-555-1212" } } @@ -97,6 +119,10 @@ services { featuredImage: "https://example.com/featured_image.png" socialImage: "https://example.com/social_image.png" description: "The main description of your release" + timestamp { + seconds: 1631839878 + nanos: 0 + } aliases: "Project Orion" tags: "CMS" tags: "SEO" @@ -107,18 +133,36 @@ services { description: "Great new feature that does something" source { name: "Acme Org" - url: "https://issues.acme.org/17240" + url: "https://issues.example.com/17240" } } resolves { type: ISSUE_CLASSIFICATION_SECURITY id: "CVE-2019-9997" name: "CVE-2019-9997" - description: "Great new feature that does something" + description: "A security issue was fixed that did something bad" source { name: "NVD" url: "https://nvd.nist.gov/vuln/detail/CVE-2019-9997" } + references: "http://some/other/site-1" + references: "http://some/other/site-2" + } + notes { + locale: "en-US" + text: { + content_type: "text/html" + encoding: "base64" + value: "PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5SZWxlYXNlIG5vdGVzIGhlcmU8L3A+" + } + } + notes { + locale: "es", + text: { + content_type: "text/html" + encoding: "base64" + value: "PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4=" + } } } } diff --git a/tools/src/test/resources/1.6/valid-release-notes-1.6.xml b/tools/src/test/resources/1.6/valid-release-notes-1.6.xml index b25986bc5..15caa3557 100644 --- a/tools/src/test/resources/1.6/valid-release-notes-1.6.xml +++ b/tools/src/test/resources/1.6/valid-release-notes-1.6.xml @@ -67,7 +67,7 @@ https://partner.org Support - support@partner + support@partner.org 800-555-1212 @@ -84,7 +84,7 @@ PII PIFI - pubic + public partner-data diff --git a/tools/src/test/resources/1.6/valid-saasbom-1.6.json b/tools/src/test/resources/1.6/valid-saasbom-1.6.json index 157e742f2..0aa16dd0d 100644 --- a/tools/src/test/resources/1.6/valid-saasbom-1.6.json +++ b/tools/src/test/resources/1.6/valid-saasbom-1.6.json @@ -264,7 +264,7 @@ { "name": "MS-3 to S3", "description": "Data pushed from microservice-3 to S3 bucket", - "classification": "Public", + "classification": "PII", "flow": "inbound", "source": [ "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#ms-3.example.com" diff --git a/tools/src/test/resources/1.6/valid-saasbom-1.6.textproto b/tools/src/test/resources/1.6/valid-saasbom-1.6.textproto index c4ee72fcc..2edfb9523 100644 --- a/tools/src/test/resources/1.6/valid-saasbom-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-saasbom-1.6.textproto @@ -6,8 +6,8 @@ version: 1 serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" metadata { timestamp { - seconds: 3173618478 - nanos: 3 + seconds: 1610280000 + nanos: 0 } component { type: CLASSIFICATION_APPLICATION @@ -34,15 +34,6 @@ services { value: "Customer" name: "Consumer to Stock Service", description: "Traffic to/from consumer to service" - governance: { - owners: [ - { - organization: { - name: "Customer Name" - } - } - ] - }, source: "https://0.0.0.0" destination: "https://0.0.0.0" } @@ -83,14 +74,24 @@ services { group: "com.example" name: "Microservice 1" version:"2022-1" + description: "Example Microservice" endpoints: "https://ms-1.example.com" authenticated: true trustZone: "Acme Private Zone" data { flow: DATA_FLOW_BI_DIRECTIONAL value: "PII" - name: "Stock Service to MS-1" + name: "Stock Service to MS-1" description: "Traffic to/from stock service to microservice-1" + governance: { + owners: [ + { + organization: { + name: "Customer Name" + } + } + ] + } source: "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#stock-ticker-service" destination: "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#stock-ticker-service" } @@ -116,6 +117,7 @@ services { group: "com.example" name: "Microservice 2" version:"2022-1" + description: "Example Microservice" endpoints: "https://ms-2.example.com" authenticated: true trustZone: "Acme Private Zone" @@ -141,6 +143,7 @@ services { group: "com.example" name: "Microservice 3" version:"2022-1" + description: "Example Microservice" endpoints: "https://ms-3.example.com" authenticated: true trustZone: "Acme Private Zone" @@ -200,8 +203,35 @@ services { } } dependencies { - ref: "pkg:maven/com.acme/stock-java-client@1.0.12" + ref: "acme-stock-application" + dependencies { + ref: "stock-ticker-service" + } +} +dependencies { + ref: "stock-ticker-service" + dependencies { + ref: "ms-1.example.com" + } + dependencies { + ref: "ms-2.example.com" + } + dependencies { + ref: "ms-3.example.com" + } +} +dependencies { + ref: "ms-1.example.com", + dependencies { + ref: "ms-1-pgsql.example.com" + } +} +dependencies { + ref: "ms-2.example.com", +} +dependencies { + ref: "ms-3.example.com", dependencies { - ref: "b2a46a4b-8367-4bae-9820-95557cfe03a8" + ref: "s3-example.amazon.com" } } diff --git a/tools/src/test/resources/1.6/valid-saasbom-1.6.xml b/tools/src/test/resources/1.6/valid-saasbom-1.6.xml index e18c7b377..433cf3d92 100644 --- a/tools/src/test/resources/1.6/valid-saasbom-1.6.xml +++ b/tools/src/test/resources/1.6/valid-saasbom-1.6.xml @@ -14,7 +14,8 @@ https://example.com com.example - Stock ticker Service + Stock Ticker Service + 2022-1 https://example.com/ https://example.com/app @@ -24,15 +25,6 @@ Customer - - - - - Customer Name - - - - https://0.0.0.0 @@ -81,6 +73,8 @@ com.example Microservice 1 + 2022-1 + Example Microservice https://ms-1.example.com @@ -89,6 +83,15 @@ PII + + + + + Customer Name + + + + urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#stock-ticker-service @@ -119,6 +122,8 @@ com.example Microservice 2 + 2022-1 + Example Microservice https://ms-2.example.com @@ -126,7 +131,7 @@ Acme Private Zone - PII + PIFI urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#stock-ticker-service @@ -148,6 +153,8 @@ com.example Microservice 3 + 2022-1 + Example Microservice https://ms-3.example.com @@ -155,7 +162,7 @@ Acme Private Zone - PII + Public urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#stock-ticker-service @@ -209,7 +216,7 @@ Public Internet - Public + PII urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#ms-3.example.com diff --git a/tools/src/test/resources/1.6/valid-service-1.6.json b/tools/src/test/resources/1.6/valid-service-1.6.json index d86841798..f5dc557d4 100644 --- a/tools/src/test/resources/1.6/valid-service-1.6.json +++ b/tools/src/test/resources/1.6/valid-service-1.6.json @@ -64,7 +64,7 @@ "flow": "outbound" }, { - "classification": "pubic", + "classification": "public", "flow": "bi-directional" }, { diff --git a/tools/src/test/resources/1.6/valid-service-1.6.textproto b/tools/src/test/resources/1.6/valid-service-1.6.textproto index 545cd7061..c43ac6974 100644 --- a/tools/src/test/resources/1.6/valid-service-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-service-1.6.textproto @@ -29,7 +29,7 @@ services { url: "https://partner.org" contact { name: "Support" - email: "support@partner" + email: "support@partner.org" phone: "800-555-1212" } } diff --git a/tools/src/test/resources/1.6/valid-service-1.6.xml b/tools/src/test/resources/1.6/valid-service-1.6.xml index 26ec84630..643effaed 100644 --- a/tools/src/test/resources/1.6/valid-service-1.6.xml +++ b/tools/src/test/resources/1.6/valid-service-1.6.xml @@ -2,6 +2,7 @@ + Acme Inc com.acme stock-java-client 1.0.12 @@ -23,7 +24,7 @@ https://partner.org Support - support@partner + support@partner.org 800-555-1212 @@ -40,7 +41,7 @@ PII PIFI - pubic + public partner-data diff --git a/tools/src/test/resources/1.6/valid-standard-1.6.textproto b/tools/src/test/resources/1.6/valid-standard-1.6.textproto index a215f12d5..3388c5cd9 100644 --- a/tools/src/test/resources/1.6/valid-standard-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-standard-1.6.textproto @@ -24,7 +24,7 @@ definitions { title: "Title here" text: "Text here" descriptions: [ - "Requirement is described here" + "Requirement is described here", "and here" ] parent: "requirement-1" diff --git a/tools/src/test/resources/1.6/valid-vulnerability-1.6.textproto b/tools/src/test/resources/1.6/valid-vulnerability-1.6.textproto index 5720fbb86..bec68ebfa 100644 --- a/tools/src/test/resources/1.6/valid-vulnerability-1.6.textproto +++ b/tools/src/test/resources/1.6/valid-vulnerability-1.6.textproto @@ -34,7 +34,7 @@ vulnerabilities { score: 9.8 severity: SEVERITY_CRITICAL method: SCORE_METHOD_CVSSV3 - vector: "AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" + vector: "AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" justification: "An optional reason for rating the vulnerability as it was" } cwes: 184 @@ -62,20 +62,20 @@ vulnerabilities { url: "https://github.com/FasterXML/jackson-databind/issues/1931" } created: { - seconds: 3173618478 - nanos: 3 + seconds: 1609459200 + nanos: 0 } published: { - seconds: 3173618478 - nanos: 3 + seconds: 1609459200 + nanos: 0 } updated: { - seconds: 3173618478 - nanos: 3 + seconds: 1609459200 + nanos: 0 } rejected: { - seconds: 3173618478 - nanos: 3 + seconds: 1640995200 + nanos: 0 } credits: { organizations: { @@ -121,12 +121,12 @@ vulnerabilities { response: VULNERABILITY_RESPONSE_UPDATE detail: "An optional explanation of why the application is not affected by the vulnerable component." firstIssued: { - seconds: 1641042000 - nanos: 3 + seconds: 1640995200 + nanos: 0 } lastUpdated: { - seconds: 1643720400 - nanos: 3 + seconds: 1643673600 + nanos: 0 } } affects: { diff --git a/tools/src/test/resources/1.6/valid-vulnerability-1.6.xml b/tools/src/test/resources/1.6/valid-vulnerability-1.6.xml index 115b91d50..33a5412f1 100644 --- a/tools/src/test/resources/1.6/valid-vulnerability-1.6.xml +++ b/tools/src/test/resources/1.6/valid-vulnerability-1.6.xml @@ -23,13 +23,6 @@ https://nvd.nist.gov/vuln/detail/CVE-2019-9997 - - CVE-2018-7489 - - NVD - https://nvd.nist.gov/vuln/detail/CVE-2019-9997 - - @@ -40,7 +33,7 @@ 9.8 critical CVSSv3 - AN/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H + AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H An optional reason for rating the vulnerability as it was @@ -101,7 +94,7 @@ - Acme Inf + Acme Inc Acme BOM Analyzer From b65dc72e4718f9843e69908cd1b61daec53ea2a9 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 19 May 2026 11:50:30 +0200 Subject: [PATCH 5/9] test: backport java tests Signed-off-by: Jan Kowalleck --- tools/pom.xml | 51 ++++-- .../schema/BaseSchemaVerificationTest.java | 15 +- .../schema/JsonSchemaVerificationTest.java | 149 ++++++++++++------ .../schema/XmlCatalogVerificationTest.java | 129 +++++++++++++++ .../schema/XmlSchemaVerificationTest.java | 147 ++++++++++++----- 5 files changed, 388 insertions(+), 103 deletions(-) create mode 100644 tools/src/test/java/org/cyclonedx/schema/XmlCatalogVerificationTest.java diff --git a/tools/pom.xml b/tools/pom.xml index 2e9263185..9667d4090 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -51,11 +51,12 @@ 1.10 3.1.0 - 2.16.1 - 3.17.0 + 2.17.0 + 3.18.0 1.12.0 + 1.5.5 1.4.9 - 9.0.5 + 2.0.16 @@ -98,6 +99,24 @@ + + + + + org.slf4j + slf4j-api + ${lib.slf4j.api} + + + + org.slf4j + slf4j-simple + ${lib.slf4j.api} + + + + + @@ -123,16 +142,22 @@ compile + + com.networknt + json-schema-validator + ${lib.json.schema.validator} + test + org.junit.jupiter - junit-jupiter-engine - 5.7.0 + junit-jupiter-api + 5.11.4 test + - org.cyclonedx - cyclonedx-core-java - ${lib.cyclonedx.core.java.version} + org.slf4j + slf4j-simple test @@ -142,8 +167,16 @@ org.apache.maven.plugins maven-surefire-plugin - 3.4.0 + 3.5.2 + + + ${project.basedir}/../schema + + + src/test/resources + + diff --git a/tools/src/test/java/org/cyclonedx/schema/BaseSchemaVerificationTest.java b/tools/src/test/java/org/cyclonedx/schema/BaseSchemaVerificationTest.java index a67565ed2..31cfc0989 100644 --- a/tools/src/test/java/org/cyclonedx/schema/BaseSchemaVerificationTest.java +++ b/tools/src/test/java/org/cyclonedx/schema/BaseSchemaVerificationTest.java @@ -33,17 +33,14 @@ List getAllResources() throws Exception { return files; } - List getResources(final String resourceDirectory) throws Exception { - final List files = new ArrayList<>(); - String dir = resourceDirectory; - if (!resourceDirectory.endsWith("/")) { - dir += "/"; - } - try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(dir)) { + private List getResources(final String resourceDirectory) throws Exception { + final List resources = new ArrayList<>(); + try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(resourceDirectory)) { if (in != null) { - files.addAll(IOUtils.readLines(in, StandardCharsets.UTF_8)); + IOUtils.readLines(in, StandardCharsets.UTF_8) + .forEach(resource -> resources.add(resourceDirectory + resource)); } } - return files; + return resources; } } diff --git a/tools/src/test/java/org/cyclonedx/schema/JsonSchemaVerificationTest.java b/tools/src/test/java/org/cyclonedx/schema/JsonSchemaVerificationTest.java index 1598c0ae6..530db0529 100644 --- a/tools/src/test/java/org/cyclonedx/schema/JsonSchemaVerificationTest.java +++ b/tools/src/test/java/org/cyclonedx/schema/JsonSchemaVerificationTest.java @@ -13,68 +13,129 @@ */ package org.cyclonedx.schema; -import java.io.File; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.networknt.schema.DefaultJsonMetaSchemaFactory; +import com.networknt.schema.DisallowUnknownKeywordFactory; +import com.networknt.schema.JsonMetaSchema; +import com.networknt.schema.JsonMetaSchemaFactory; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.NonValidationKeyword; +import com.networknt.schema.SchemaId; +import com.networknt.schema.SchemaLocation; +import com.networknt.schema.SchemaValidatorsConfig; +import com.networknt.schema.resource.ClasspathSchemaLoader; +import com.networknt.schema.resource.DisallowSchemaLoader; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; - -import org.cyclonedx.parsers.JsonParser; -import org.cyclonedx.Version; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.assertFalse; +class JsonSchemaVerificationTest extends BaseSchemaVerificationTest { + + private static final ObjectMapper MAPPER = new JsonMapper(); + + private static final String JSF_NAMESPACE = "http://cyclonedx.org/schema/jsf-0.82.schema.json"; + private static final String SPDX_NAMESPACE = "http://cyclonedx.org/schema/spdx.schema.json"; + private static final String CRYPTO_DEF_NAMESPACE = "http://cyclonedx.org/schema/cryptography-defs.schema.json"; + + private static final JsonSchema VERSION_12; + private static final JsonSchema VERSION_13; + private static final JsonSchema VERSION_14; + private static final JsonSchema VERSION_15; + private static final JsonSchema VERSION_16; + + static { + JsonMetaSchemaFactory metaSchemaFactory = new DefaultJsonMetaSchemaFactory() { + @Override + public JsonMetaSchema getMetaSchema( + String iri, JsonSchemaFactory schemaFactory, SchemaValidatorsConfig config) { + return addCustomKeywords(super.getMetaSchema(iri, schemaFactory, config)); + } + }; + JsonSchemaFactory factory = JsonSchemaFactory.builder() + .defaultMetaSchemaIri(SchemaId.V7) + .metaSchema(addCustomKeywords(JsonMetaSchema.getV7())) + .metaSchemaFactory(metaSchemaFactory) + .schemaLoaders(b -> b.add(new ClasspathSchemaLoader()).add(DisallowSchemaLoader.getInstance())) + .schemaMappers(b -> b.mapPrefix(SPDX_NAMESPACE, "classpath:spdx.schema.json") + .mapPrefix(JSF_NAMESPACE, "classpath:jsf-0.82.schema.json") + .mapPrefix(CRYPTO_DEF_NAMESPACE, "classpath:cryptography-defs.schema.json") + ).build(); + VERSION_12 = factory.getSchema(SchemaLocation.of("classpath:bom-1.2-strict.schema.json")); + VERSION_13 = factory.getSchema(SchemaLocation.of("classpath:bom-1.3-strict.schema.json")); + VERSION_14 = factory.getSchema(SchemaLocation.of("classpath:bom-1.4.schema.json")); + VERSION_15 = factory.getSchema(SchemaLocation.of("classpath:bom-1.5.schema.json")); + VERSION_16 = factory.getSchema(SchemaLocation.of("classpath:bom-1.6.schema.json")); + } -public class JsonSchemaVerificationTest extends BaseSchemaVerificationTest { + private static JsonMetaSchema addCustomKeywords(JsonMetaSchema metaSchema) { + return JsonMetaSchema.builder(metaSchema) + // Non-standard keywords in the CycloneDX schema files. + .keyword(new NonValidationKeyword("deprecated")) + .keyword(new NonValidationKeyword("meta:enum")) + .unknownKeywordFactory(new DisallowUnknownKeywordFactory()) + .build(); + } @TestFactory Collection dynamicTestsWithCollection() throws Exception { - final List files = getAllResources(); + final List resources = getAllResources(); final List dynamicTests = new ArrayList<>(); - for (final String file: files) { - if (file.endsWith(".json")) { - final Version schemaVersion; - if (file.endsWith("-1.2.json")) { - schemaVersion = Version.VERSION_12; - } else if (file.endsWith("-1.3.json")) { - schemaVersion = Version.VERSION_13; - } else if (file.endsWith("-1.4.json")) { - schemaVersion = Version.VERSION_14; - } else if (file.endsWith("-1.5.json")) { - schemaVersion = Version.VERSION_15; - } else if (file.endsWith("-1.6.json")) { - schemaVersion = Version.VERSION_16; - } else { - schemaVersion = null; - } - if (file.startsWith("valid") && schemaVersion != null) { - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertTrue( - isValidJson(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); - } else if (file.startsWith("invalid") && schemaVersion != null) { - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertFalse( - isValidJson(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); + for (final String resource : resources) { + String resourceName = StringUtils.substringAfterLast(resource, "/"); + if (resourceName.endsWith(".json")) { + JsonSchema schema = getSchema(resourceName); + if (schema != null) { + if (resourceName.startsWith("valid")) { + dynamicTests.add(DynamicTest.dynamicTest( + resource, () -> assertTrue(isValid(schema, resource), resource))); + } else if (resourceName.startsWith("invalid")) { + dynamicTests.add(DynamicTest.dynamicTest( + resource, () -> assertFalse(isValid(schema, resource), resource))); + } } } } return dynamicTests; } - private boolean isValidJson(Version version, String resource) throws Exception { - final File file = new File(this.getClass().getResource(resource).getFile()); - final JsonParser parser = new JsonParser(); - return parser.isValid(file, version); - - // Uncomment to provide more detailed validation errors - /* - try { - final String jsonString = FileUtils.readFileToString(file, StandardCharsets.UTF_8); - parser.getJsonSchema(version, true).validate(new JSONObject(jsonString)); - return true; - } catch (ValidationException e) { - e.printStackTrace(); + private boolean isValid(JsonSchema schema, String resource) { + try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource); + JsonParser parser = MAPPER.createParser(input)) { + JsonNode node = parser.readValueAsTree(); + return schema.validate(node).isEmpty(); + } catch (IOException e) { return false; } - */ + } + + private JsonSchema getSchema(String resourceName) { + if (resourceName.endsWith("-1.2.json")) { + return VERSION_12; + } + if (resourceName.endsWith("-1.3.json")) { + return VERSION_13; + } + if (resourceName.endsWith("-1.4.json")) { + return VERSION_14; + } + if (resourceName.endsWith("-1.5.json")) { + return VERSION_15; + } + if (resourceName.endsWith("-1.6.json")) { + return VERSION_16; + } + return null; } } diff --git a/tools/src/test/java/org/cyclonedx/schema/XmlCatalogVerificationTest.java b/tools/src/test/java/org/cyclonedx/schema/XmlCatalogVerificationTest.java new file mode 100644 index 000000000..30df90312 --- /dev/null +++ b/tools/src/test/java/org/cyclonedx/schema/XmlCatalogVerificationTest.java @@ -0,0 +1,129 @@ +package org.cyclonedx.schema; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static org.junit.jupiter.api.DynamicTest.dynamicTest; + +public class XmlCatalogVerificationTest { + + /** + * Tests the XML catalog by parsing the xmlcatalog.xml file and verifying if the XML namespaces + * in the referenced XSD schema files match the XML namespaces defined in the xmlcatalog.xml file. + * + * @return a list of dynamic tests for each URI in the xmlcatalog.xml file + * @throws IOException if an I/O error occurs while reading the XML catalog file + * @throws ParserConfigurationException if a parser configuration error occurs + * @throws SAXException if a SAX error occurs while parsing the XML catalog file + * @throws XPathExpressionException if an XPath expression error occurs + */ + @TestFactory + public List testXmlCatalog() throws IOException, ParserConfigurationException, SAXException, XPathExpressionException { + // Define the path to the XML catalog file. This is relative to "${basedir}/../schema" in the pom.xml. + String xmlCatalogFilename = "xmlcatalog.xml"; + + // Load the XML catalog file from the classpath + ClassLoader classLoader = getClass().getClassLoader(); + InputStream xmlCatalogStream = classLoader.getResourceAsStream(xmlCatalogFilename); + + // Ensure the XML catalog file is found + Assertions.assertNotNull(xmlCatalogStream, "XML catalog file not found"); + + // Parse the xmlcatalog.xml file + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); // Make the factory namespace-aware + DocumentBuilder builder = factory.newDocumentBuilder(); + Document xmlCatalogDocument = builder.parse(new InputSource(xmlCatalogStream)); + + // Get the XML catalog elements + NodeList xmlCatalogElements = xmlCatalogDocument.getDocumentElement().getChildNodes(); + + // List to hold dynamic tests + List dynamicTests = new ArrayList<>(); + + // Iterate through the XML catalog elements + for (int i = 0; i < xmlCatalogElements.getLength(); i++) { + Node xmlCatalogElement = xmlCatalogElements.item(i); + + // Check if the element is a element, continue if it is not + if (!xmlCatalogElement.getNodeName().equals("uri")) { + continue; + } + + // Get the URI name and the local filename of the XSD schema + String uriNameXmlCtlg = xmlCatalogElement.getAttributes().getNamedItem("name").getTextContent(); + String xsdLocalFilename = xmlCatalogElement.getAttributes().getNamedItem("uri").getTextContent(); + + // Load the XSD schema local file from the classpath + InputStream xsdSchemaFileStream = classLoader.getResourceAsStream(xsdLocalFilename); + Assertions.assertNotNull(xsdSchemaFileStream, "The following file is missing: " + xsdLocalFilename); + + // Parse the XSD schema local file + DocumentBuilderFactory factoryXsd = DocumentBuilderFactory.newInstance(); + factoryXsd.setNamespaceAware(true); // Make the factory namespace-aware + DocumentBuilder builderXsd = factoryXsd.newDocumentBuilder(); + Document xsdDocument = builderXsd.parse(new InputSource(xsdSchemaFileStream)); + + // Create an XPath instance to evaluate the targetNamespace field found in the XSD local schema file + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.setNamespaceContext(new NamespaceContext() { + @Override + public String getNamespaceURI(String prefix) { + // Define the namespace URI for the xs prefix + if ("xs".equals(prefix)) { + return "http://www.w3.org/2001/XMLSchema"; + } + return null; + } + + @Override + public String getPrefix(String namespaceURI) { + // Define the prefix for the namespace URI + if ("http://www.w3.org/2001/XMLSchema".equals(namespaceURI)) { + return "xs"; + } + return null; + } + + @Override + public Iterator getPrefixes(String namespaceURI) { + return null; + } + }); + + // Evaluate the targetNamespace attribute from the XSD document + String targetNamespace = (String) xPath.evaluate("/xs:schema/@targetNamespace", xsdDocument, XPathConstants.STRING); + + // Create a dynamic test for each URI + dynamicTests.add(dynamicTest("Testing if URI namespace from the XML catalog: " + uriNameXmlCtlg + " matches the URI namespace from the local XSD file: " + targetNamespace, () -> { + // Assert if the targetNamespace from the XSD file matches the uriNameXmlCtlg from the XML catalog + Assertions.assertEquals(uriNameXmlCtlg, targetNamespace, "The namespace " + uriNameXmlCtlg + " does not match the targetNamespace in file " + xsdLocalFilename); + })); + } + + // Return the list of dynamic tests + return dynamicTests; + } +} diff --git a/tools/src/test/java/org/cyclonedx/schema/XmlSchemaVerificationTest.java b/tools/src/test/java/org/cyclonedx/schema/XmlSchemaVerificationTest.java index 2d57dd8a9..348d9e5b0 100644 --- a/tools/src/test/java/org/cyclonedx/schema/XmlSchemaVerificationTest.java +++ b/tools/src/test/java/org/cyclonedx/schema/XmlSchemaVerificationTest.java @@ -13,57 +13,77 @@ */ package org.cyclonedx.schema; -import java.io.File; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.ArrayList; import java.util.Collection; import java.util.List; - -import org.cyclonedx.parsers.XmlParser; -import org.cyclonedx.Version; +import javax.xml.XMLConstants; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; - -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.assertFalse; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; public class XmlSchemaVerificationTest extends BaseSchemaVerificationTest { - @TestFactory + private static final Schema VERSION_10; + private static final Schema VERSION_11; + private static final Schema VERSION_12; + private static final Schema VERSION_13; + private static final Schema VERSION_14; + private static final Schema VERSION_15; + private static final Schema VERSION_16; + + static { + try { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "file"); + ClassLoader cl = XmlSchemaVerificationTest.class.getClassLoader(); + // Override the `schemaLocation` property in the file + factory.setProperty( + "http://apache.org/xml/properties/schema/external-schemaLocation", + "http://cyclonedx.org/schema/spdx spdx.xsd"); + VERSION_10 = factory.newSchema(cl.getResource("bom-1.0.xsd")); + VERSION_11 = factory.newSchema(cl.getResource("bom-1.1.xsd")); + VERSION_12 = factory.newSchema(cl.getResource("bom-1.2.xsd")); + VERSION_13 = factory.newSchema(cl.getResource("bom-1.3.xsd")); + VERSION_14 = factory.newSchema(cl.getResource("bom-1.4.xsd")); + VERSION_15 = factory.newSchema(cl.getResource("bom-1.5.xsd")); + VERSION_16 = factory.newSchema(cl.getResource("bom-1.6.xsd")); + } catch (SAXException e) { + throw new IllegalStateException(e); + } + } + /** * Generates a collection of dynamic tests based on the available XML files. * * @return Collection a collection of dynamic tests * @throws Exception if an error occurs during the generation of the dynamic tests */ + @TestFactory Collection dynamicTestsWithCollection() throws Exception { - final List files = getAllResources(); + final List resources = getAllResources(); final List dynamicTests = new ArrayList<>(); - for (final String file: files) { - if (file.endsWith(".xml")) { - final Version schemaVersion; - if (file.endsWith("-1.0.xml")) { - schemaVersion = Version.VERSION_10; - } else if (file.endsWith("-1.1.xml")) { - schemaVersion = Version.VERSION_11; - } else if (file.endsWith("-1.2.xml")) { - schemaVersion = Version.VERSION_12; - } else if (file.endsWith("-1.3.xml")) { - schemaVersion = Version.VERSION_13; - } else if (file.endsWith("-1.4.xml")) { - schemaVersion = Version.VERSION_14; - } else if (file.endsWith("-1.5.xml")) { - schemaVersion = Version.VERSION_15; - } else if (file.endsWith("-1.6.xml")) { - schemaVersion = Version.VERSION_16; - } else { - schemaVersion = null; - } - if (file.startsWith("valid") && schemaVersion != null) { - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertTrue( - isValid(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); - } else if (file.startsWith("invalid") && schemaVersion != null) { - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertFalse( - isValid(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); + for (final String resource : resources) { + String resourceName = StringUtils.substringAfterLast(resource, "/"); + if (resourceName.endsWith(".xml")) { + Schema schema = getSchema(resourceName); + if (schema != null) { + if (resourceName.startsWith("valid")) { + dynamicTests.add(DynamicTest.dynamicTest( + resource, () -> assertTrue(isValid(schema, resource), resource))); + } else if (resourceName.startsWith("invalid")) { + dynamicTests.add(DynamicTest.dynamicTest( + resource, () -> assertFalse(isValid(schema, resource), resource))); + } } } } @@ -73,14 +93,59 @@ Collection dynamicTestsWithCollection() throws Exception { /** * Validates the given XML file against the specified CycloneDX schema version. * - * @param version the CycloneDX schema version to validate against - * @param resource the path to the XML file to be validated + * @param schema the CycloneDX schema to validate against + * @param resource the path to the XML file to be validated * @return boolean true if the XML file is valid according to the specified schema version, false otherwise * @throws Exception if an error occurs during the validation process */ - private boolean isValid(Version version, String resource) throws Exception { - final File file = new File(this.getClass().getResource(resource).getFile()); - final XmlParser parser = new XmlParser(); - return parser.isValid(file, version); + private boolean isValid(Schema schema, String resource) throws Exception { + Validator validator = schema.newValidator(); + validator.setErrorHandler(new ErrorHandler() { + @Override + public void warning(SAXParseException exception) throws SAXException { + throw exception; + } + + @Override + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + throw exception; + } + }); + try { + validator.validate(new StreamSource(getClass().getClassLoader().getResourceAsStream(resource))); + } catch (SAXParseException e) { + return false; + } + return true; + } + + private Schema getSchema(String resourceName) { + if (resourceName.endsWith("-1.0.xml")) { + return VERSION_10; + } + if (resourceName.endsWith("-1.1.xml")) { + return VERSION_11; + } + if (resourceName.endsWith("-1.2.xml")) { + return VERSION_12; + } + if (resourceName.endsWith("-1.3.xml")) { + return VERSION_13; + } + if (resourceName.endsWith("-1.4.xml")) { + return VERSION_14; + } + if (resourceName.endsWith("-1.5.xml")) { + return VERSION_15; + } + if (resourceName.endsWith("-1.6.xml")) { + return VERSION_16; + } + return null; } } From 6894c1894c0b8b52b1bf3374958a861633ef105d Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 19 May 2026 19:42:36 +0200 Subject: [PATCH 6/9] test: backport js tests Signed-off-by: Jan Kowalleck --- tools/src/test/js/json-schema-functional-tests.js | 5 +++-- tools/src/test/js/json-schema-lint-tests.js | 5 +++-- tools/src/test/js/package.json | 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tools/src/test/js/json-schema-functional-tests.js b/tools/src/test/js/json-schema-functional-tests.js index b165e65ed..e2b849238 100644 --- a/tools/src/test/js/json-schema-functional-tests.js +++ b/tools/src/test/js/json-schema-functional-tests.js @@ -55,9 +55,10 @@ const ajv = new Ajv({ strict: false, validateFormats: true, addUsedSchema: false, + loadSchema: (uri) => { throw new Error(`Remote schemas are disabled: ${uri}`) }, schemas: { 'http://cyclonedx.org/schema/spdx.schema.json': spdxSchema, - 'http://cyclonedx.org/schema/jsf-0.82.schema.json': jsfSchema + 'http://cyclonedx.org/schema/jsf-0.82.schema.json': jsfSchema, } }); addFormats(ajv) @@ -113,4 +114,4 @@ for (const file of globSync(join(testdataDir, 'invalid-*.json'))) { // Exit statuses should be in the range 0 to 254. // The status 0 is used to terminate the program successfully. -process.exitCode = Math.min(errCnt, 254) \ No newline at end of file +process.exitCode = Math.min(errCnt, 254) diff --git a/tools/src/test/js/json-schema-lint-tests.js b/tools/src/test/js/json-schema-lint-tests.js index 5033ac6bc..7d35972b0 100644 --- a/tools/src/test/js/json-schema-lint-tests.js +++ b/tools/src/test/js/json-schema-lint-tests.js @@ -51,9 +51,10 @@ function getAjv(strict) { addUsedSchema: false, allowUnionTypes: false, keywords: ["meta:enum"], + loadSchema: (uri) => { throw new Error(`Remote schemas are disabled: ${uri}`) }, schemas: { 'http://cyclonedx.org/schema/spdx.schema.json': spdxSchema, - 'http://cyclonedx.org/schema/jsf-0.82.schema.json': jsfSchema + 'http://cyclonedx.org/schema/jsf-0.82.schema.json': jsfSchema, } }); addFormats(ajv) @@ -112,4 +113,4 @@ for (const bomSchemaFile of bomSchemas) { // Exit statuses should be in the range 0 to 254. // The status 0 is used to terminate the program successfully. -process.exitCode = Math.min(errCnt, 254) \ No newline at end of file +process.exitCode = Math.min(errCnt, 254) diff --git a/tools/src/test/js/package.json b/tools/src/test/js/package.json index 441ef8d7c..cdc8b63a5 100644 --- a/tools/src/test/js/package.json +++ b/tools/src/test/js/package.json @@ -8,16 +8,16 @@ "ajv": "^8.12.0", "ajv-formats": "^3.0.1", "ajv-formats-draft2019": "^1.6.1", - "glob": "^11.0.0", + "glob": "^13.0.0", "npm-run-all": "^4.1.5" }, "devDependencies": { "@types/node": ">=18.3" }, "scripts": { - "test": "run-s test:*", + "test": "run-s test:\\*", "test:json-schema-lint": "node -- json-schema-lint-tests.js", - "test:json-schema-functional": "run-s test:json-schema-functional:*", + "test:json-schema-functional": "run-s test:json-schema-functional:\\*", "test:json-schema-functional:1.6": "node -- json-schema-functional-tests.js -v 1.6", "test:json-schema-functional:1.5": "node -- json-schema-functional-tests.js -v 1.5", "test:json-schema-functional:1.4": "node -- json-schema-functional-tests.js -v 1.4", From f23ffdb3d8b79b592ed00050278fa3ab9a071e0c Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 19 May 2026 19:42:43 +0200 Subject: [PATCH 7/9] test: backport php tests Signed-off-by: Jan Kowalleck --- tools/src/test/php/composer.json | 4 ++-- tools/src/test/php/json-schema-functional-tests.php | 2 +- tools/src/test/php/xml-schema-functional-tests.php | 12 ++++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tools/src/test/php/composer.json b/tools/src/test/php/composer.json index 76c26c2af..9e3677ec5 100644 --- a/tools/src/test/php/composer.json +++ b/tools/src/test/php/composer.json @@ -5,7 +5,7 @@ "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", - "opis/json-schema": "2.3" + "opis/json-schema": "2.6.0" }, "require-dev": { "roave/security-advisories": "dev-latest" @@ -50,4 +50,4 @@ "test": "run all tests", "test:json-schema-lint": "lint JSON schema." } -} \ No newline at end of file +} diff --git a/tools/src/test/php/json-schema-functional-tests.php b/tools/src/test/php/json-schema-functional-tests.php index 4b7e460ec..0e4530a3a 100644 --- a/tools/src/test/php/json-schema-functional-tests.php +++ b/tools/src/test/php/json-schema-functional-tests.php @@ -90,4 +90,4 @@ function validateFile(string $file): ?JsonSchema\Errors\ValidationError // Exit statuses should be in the range 0 to 254, the exit status 255 is reserved by PHP and shall not be used. // The status 0 is used to terminate the program successfully. -exit(min($errCnt, 254)); \ No newline at end of file +exit(min($errCnt, 254)); diff --git a/tools/src/test/php/xml-schema-functional-tests.php b/tools/src/test/php/xml-schema-functional-tests.php index 2646de5c7..e5d4da638 100644 --- a/tools/src/test/php/xml-schema-functional-tests.php +++ b/tools/src/test/php/xml-schema-functional-tests.php @@ -14,6 +14,8 @@ define('TESTSCHEMA_VERSION', getopt('v:')['v']); define('SCHEMA_DIR', realpath(__DIR__ . '/../../../../schema')); define('SCHEMA_FILE', SCHEMA_DIR . '/bom-' . TESTSCHEMA_VERSION . '.xsd'); +define('SPDX_FILE', SCHEMA_DIR . '/spdx.xsd'); + define('TESTDATA_DIR', realpath(__DIR__ . '/../resources/' . TESTSCHEMA_VERSION)); if (empty(TESTSCHEMA_VERSION)) { @@ -58,7 +60,13 @@ function validateFile(string $file): ?LibXMLError throw new Exception("failed loading file: $file" . PHP_EOL . libxml_get_last_error()->message); } - $valid = $doc->schemaValidate(SCHEMA_FILE); + $xsd = str_replace( + 'schemaLocation="http://cyclonedx.org/schema/spdx"', + 'schemaLocation="file://'. htmlspecialchars(SPDX_FILE, ENT_XML1, 'UTF-8') .'"', + file_get_contents(SCHEMA_FILE) + ); + + $valid = $doc->schemaValidateSource($xsd, LIBXML_SCHEMA_CREATE); return $valid ? null : libxml_get_last_error(); @@ -96,4 +104,4 @@ function validateFile(string $file): ?LibXMLError // Exit statuses should be in the range 0 to 254, the exit status 255 is reserved by PHP and shall not be used. // The status 0 is used to terminate the program successfully. -exit(min($errCnt, 254)); \ No newline at end of file +exit(min($errCnt, 254)); From bf9cfea5480f03cce4fb3caa602fbea73e96d2e1 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 19 May 2026 19:42:51 +0200 Subject: [PATCH 8/9] test: backport proto tests Signed-off-by: Jan Kowalleck --- .../src/test/proto/buf_breaking-version.yaml | 11 ++- tools/src/test/proto/test.sh | 71 +++++++++---------- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/tools/src/test/proto/buf_breaking-version.yaml b/tools/src/test/proto/buf_breaking-version.yaml index e3fecdfd4..9ab710785 100644 --- a/tools/src/test/proto/buf_breaking-version.yaml +++ b/tools/src/test/proto/buf_breaking-version.yaml @@ -3,4 +3,13 @@ version: v2 breaking: # https://buf.build/docs/configuration/v2/buf-yaml#breaking use: # see https://buf.build/docs/breaking/overview#rules-and-categories - - WIRE \ No newline at end of file + - WIRE + ignore_only: + # possible breaks are acknowledged for this specific findings only + FIELD_WIRE_COMPATIBLE_CARDINALITY: + # DO NOT ADD NEW VERSIONS HERE WITHOUT CONSULTING THE CDX CORE-WORKING-GROUP + - 'schema/bom-1.6.proto' + - 'schema/bom-1.5.proto' + FIELD_WIRE_COMPATIBLE_TYPE: + # DO NOT ADD NEW VERSIONS HERE WITHOUT CONSULTING THE CDX CORE-WORKING-GROUP + - 'schema/bom-1.5.proto' diff --git a/tools/src/test/proto/test.sh b/tools/src/test/proto/test.sh index 8d0c72ada..aaa5a18ae 100755 --- a/tools/src/test/proto/test.sh +++ b/tools/src/test/proto/test.sh @@ -10,27 +10,32 @@ TEST_RES_DIR='tools/src/test/resources' REMOTE="https://github.com/${GITHUB_REPOSITORY:-CycloneDX/specification}.git" -BUF_IMAGE_VERSION='1.46.0' +BUF_IMAGE_VERSION='1.58.0' +BUF_IMAGE="bufbuild/buf:${BUF_IMAGE_VERSION}" + +LOG_FORMAT='text' # set to 'json' to see details +if [[ -n "${GITHUB_WORKFLOW:-}" ]] +then + LOG_FORMAT='github-actions' +fi ## ---- +function prepare () { + docker pull "$BUF_IMAGE" +} + + function schema-lint () { echo '> lint schema files' >&2 - if [[ -n "${GITHUB_WORKFLOW:-}" ]] - then - LOG_FORMAT='github-actions' - else - LOG_FORMAT='text' - fi - docker run --rm \ --volume "${ROOT_PATH}/${SCHEMA_DIR}:/workspace/${SCHEMA_DIR}:ro" \ --volume "${THIS_PATH}/buf_lint.yaml:/workspace/buf.yaml:ro" \ --workdir '/workspace' \ - bufbuild/buf:"$BUF_IMAGE_VERSION" \ + "$BUF_IMAGE" \ lint --path "$SCHEMA_DIR" \ --error-format "$LOG_FORMAT" @@ -41,21 +46,15 @@ function schema-lint () { function schema-breaking-version () { echo '> test schema for breaking changes against previous version' >&2 - if [[ -n "${GITHUB_WORKFLOW:-}" ]] - then - LOG_FORMAT='github-actions' - else - LOG_FORMAT='text' - fi - function compare() { - NEW="bom-${1}.proto" - OLD="bom-${2}.proto" + local NEW="bom-${1}.proto" + local OLD="bom-${2}.proto" + local NEW_NP OLD_NP NEW_NP="$(mktemp)" OLD_NP="$(mktemp)" - # remove package identifier -> so that the comparisson works as expected + # remove package identifier -> so that the comparison works as expected sed 's/^package .*//' "${ROOT_PATH}/${SCHEMA_DIR}/${NEW}" > "$NEW_NP" sed 's/^package .*//' "${ROOT_PATH}/${SCHEMA_DIR}/${OLD}" > "$OLD_NP" @@ -66,14 +65,14 @@ function schema-breaking-version () { --volume "${NEW_NP}:/workspaces/new/${SCHEMA_DIR}/${NEW}:ro" \ --volume "${THIS_PATH}/buf_breaking-version.yaml:/workspaces/new/buf.yaml:ro" \ --workdir '/workspaces/new' \ - bufbuild/buf:"$BUF_IMAGE_VERSION" \ + "$BUF_IMAGE" \ breaking \ --against ../old \ --error-format "$LOG_FORMAT" } - # compare '1.6' '1.5' # <-- possible breaks are acknowledged - # compare '1.5' '1.4' # <-- possible breaks are acknowledged + compare '1.6' '1.5' || echo "possible breaks are acknowledged for this specific version only" + compare '1.5' '1.4' || echo "possible breaks are acknowledged for this specific version only" compare '1.4' '1.3' echo '>> OK.' >&2 @@ -82,20 +81,13 @@ function schema-breaking-version () { function schema-breaking-remote () { echo '> test schema for breaking changes against remote' >&2 - if [[ -n "${GITHUB_WORKFLOW:-}" ]] - then - LOG_FORMAT='github-actions' - else - LOG_FORMAT='text' - fi - docker run --rm \ --volume "${ROOT_PATH}/${SCHEMA_DIR}:/workspace/${SCHEMA_DIR}:ro" \ --volume "${THIS_PATH}/buf_breaking-remote.yaml:/workspace/buf.yaml:ro" \ --workdir '/workspace' \ - bufbuild/buf:"$BUF_IMAGE_VERSION" \ + "$BUF_IMAGE" \ breaking --path "$SCHEMA_DIR" \ - --against "${REMOTE}" \ + --against "$REMOTE" \ --error-format "$LOG_FORMAT" echo '>> OK.' >&2 @@ -105,10 +97,10 @@ function schema-functional () { echo '> test all examples against the respective schema' >&2 function validate() { - FILE="$1" - SCHEMA_VERS="$2" - SCHEMA_FILE="bom-${SCHEMA_VERS}.proto" - MESSAGE="cyclonedx.v${SCHEMA_VERS/./_}.Bom" + local FILE="$1" + local SCHEMA_VERS="$2" + local SCHEMA_FILE="bom-${SCHEMA_VERS}.proto" + local MESSAGE="cyclonedx.v${SCHEMA_VERS/./_}.Bom" echo ">> validate $(realpath --relative-to="$PWD" "$FILE") as ${MESSAGE} of ${SCHEMA_FILE}" >&2 @@ -118,13 +110,14 @@ function schema-functional () { --volume "${ROOT_PATH}/${SCHEMA_DIR}:/workspace/${SCHEMA_DIR}:ro" \ --volume "${FILE}:/workspace/test_res:ro" \ --workdir '/workspace' \ - bufbuild/buf:"$BUF_IMAGE_VERSION" \ + "$BUF_IMAGE" \ convert "${SCHEMA_DIR}/${SCHEMA_FILE}" \ --type "$MESSAGE" \ --from 'test_res#format=txtpb' \ --to /dev/null } + local SCHEMA_VERS shopt -s globstar for test_res in "$ROOT_PATH"/"$TEST_RES_DIR"/*/valid-*.textproto do @@ -141,23 +134,29 @@ function schema-functional () { case "${1:-all}" in 'schema-lint') + prepare schema-lint ;; 'schema-breaking-version') + prepare schema-breaking-version ;; 'schema-breaking-remote') + prepare schema-breaking-remote ;; 'schema-breaking') + prepare schema-breaking-version schema-breaking-remote ;; 'schema-functional') + prepare schema-functional ;; 'all') # all the above + prepare schema-lint schema-breaking-version schema-breaking-remote From 1f8cc2e9ded61e7957d7f65754da29209be6bb30 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Tue, 19 May 2026 19:57:07 +0200 Subject: [PATCH 9/9] test: backport CT pipelines Signed-off-by: Jan Kowalleck --- .github/workflows/build_docs.yml | 3 +++ .github/workflows/test_java.yml | 11 ++++++++--- .github/workflows/test_js.yml | 16 +++++++++++----- .github/workflows/test_php.yml | 13 +++++++++---- .github/workflows/test_proto.yml | 9 +++++++-- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index 2d0b41e92..a3dc889f5 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -9,6 +9,9 @@ on: env: PYTHON_VERSION_DEFAULT: "3.10" +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + jobs: docs_xml: runs-on: ubuntu-latest diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml index dfbcc7841..5935a22c0 100644 --- a/.github/workflows/test_java.yml +++ b/.github/workflows/test_java.yml @@ -14,16 +14,21 @@ defaults: run: working-directory: tools +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + jobs: - test: + test_java: runs-on: ubuntu-latest steps: - name: Checkout # see https://github.com/actions/checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false - name: Set up JDK # see https://github.com/actions/setup-java - uses: actions/setup-java@v4 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 with: java-version: '8' distribution: 'zulu' diff --git a/.github/workflows/test_js.yml b/.github/workflows/test_js.yml index 4502b200e..ee3db0f0b 100644 --- a/.github/workflows/test_js.yml +++ b/.github/workflows/test_js.yml @@ -16,20 +16,26 @@ defaults: run: working-directory: tools/src/test/js +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + jobs: - test: + test_js: timeout-minutes: 30 runs-on: ubuntu-latest steps: - name: Checkout # see https://github.com/actions/checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false - name: Setup Node.js # see https://github.com/actions/setup-node - uses: actions/setup-node@v4 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '20.x' - - name: Install Depenencies + node-version: '24.x' + package-manager-cache: false + - name: Install Dependencies run: npm install - name: Run test run: npm test diff --git a/.github/workflows/test_php.yml b/.github/workflows/test_php.yml index 498acebf5..e6259aa25 100644 --- a/.github/workflows/test_php.yml +++ b/.github/workflows/test_php.yml @@ -16,19 +16,24 @@ defaults: run: working-directory: tools/src/test/php +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + jobs: - test: + test_php: timeout-minutes: 30 runs-on: ubuntu-latest steps: - name: Checkout # see https://github.com/actions/checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false - name: Setup PHP # see https://github.com/shivammathur/setup-php - uses: shivammathur/setup-php@v2 + uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2 with: - php-version: "8.1" + php-version: "8.4" tools: composer:v2 - name: Install Depenencies run: composer install diff --git a/.github/workflows/test_proto.yml b/.github/workflows/test_proto.yml index 0dfe8cae5..65847affc 100644 --- a/.github/workflows/test_proto.yml +++ b/.github/workflows/test_proto.yml @@ -16,13 +16,18 @@ defaults: run: working-directory: tools/src/test/proto +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + jobs: - test: + test_proto: timeout-minutes: 30 runs-on: ubuntu-latest steps: - name: Checkout # see https://github.com/actions/checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false - name: Run test run: ./test.sh